在Python中测试私有方法:单元测试还是功能测试?
在阅读关于如何测试Python中的私有方法时,特别是参考了这个被接受的回答,我发现最好还是只测试公共接口。不过,我的类是这样的:
class MyClass:
def __init__(self):
# init code
def run(self):
self.__A()
self.__B()
self.__C()
self.__D()
def __A(self):
# code for __A
def __B(self):
# code for __B
def __C(self):
# code for __C
def __D(self):
# code for __D
简单来说,我创建了一个类,用来通过一系列函数处理一些输入数据。在这种情况下,逐个测试每个私有函数会很有帮助,但又不想把它们暴露成公共函数。如果单元测试不能执行私有函数,那该怎么做呢?
3 个回答
-1
你可能只需要测试一下 run()
这个方法。大多数类里面都会有一些内部方法,而在这种情况下,__A()
、__B()
、__C()
和 __D()
这些方法里的代码是否都在 run()
里面其实并不重要。如果你怀疑或者发现了问题,那你可以切换到调试模式,去测试一下那些私有方法。
62
在Python中,当它把实际执行的代码组合在一起时,会对一些名字进行处理。所以,如果你在MyClass
里有一个私有方法__A
,在你的单元测试中调用它时,你需要这样做:
from unittest import TestCase
class TestMyClass(TestCase):
def test_private(self):
expected = 'myexpectedresult'
m = MyClass()
actual = m._MyClass__A
self.assertEqual(expected, actual)
还有人提到所谓的“受保护”值,这些值的名字前面有一个下划线。这样的名字是不会被处理的,这一点可以很简单地证明:
from unittest import TestCase
class A:
def __a(self):
return "myexpectedresult"
def _b(self):
return "a different result"
class TestMyClass(TestCase):
def test_private(self):
expected = "myexpectedresult"
m = A()
actual = m._A__a()
self.assertEqual(expected, actual)
def test_protected(self):
expected = "a different result"
m = A()
actual = m._b()
self.assertEqual(expected, actual)
# actual = m._A__b() # Fails
# actual = m._A_b() # Fails
14
首先,你可以访问那些“私有”的东西,对吧?(或者我是不是漏掉了什么?)
>>> class MyClass(object):
... def __init__(self):
... pass
... def __A(self):
... print('Method __A()')
...
>>> a=MyClass()
>>> a
<__main__.MyClass object at 0x101d56b50>
>>> a._MyClass__A()
Method __A()
不过,如果你需要测试内部的内容,你可以在 MyClass
里写一个测试函数:
class MyClass(object):
...
def _method_for_unit_testing(self):
self.__A()
assert <something>
self.__B()
assert <something>
....
这确实不是最优雅的做法,但在你类的底部只需要几行代码。