sky*_*der 5 python unit-testing unittest2
我是使用Python在单元测试类unittest.据我了解,在每次测试之前unittest调用setUp函数,以便单元测试对象的状态相同,执行测试的顺序无关紧要.
现在我有这门课,我正在测试......
#! usr/bin/python2
class SpamTest(object):
def __init__(self, numlist = []):
self.__numlist = numlist
@property
def numlist(self):
return self.__numlist
@numlist.setter
def numlist(self, numlist):
self.__numlist = numlist
def add_num(self, num):
self.__numlist.append(num)
def incr(self, delta):
self.numlist = map(lambda x: x + 1, self.numlist)
def __eq__(self, st2):
i = 0
limit = len(self.numlist)
if limit != len(st2.numlist):
return False
while i < limit:
if self.numlist[i] != st2.numlist[i]:
return False
i += 1
return True
Run Code Online (Sandbox Code Playgroud)
通过以下单元测试......
#! usr/bin/python2
from test import SpamTest
import unittest
class Spammer(unittest.TestCase):
def setUp(self):
self.st = SpamTest()
#self.st.numlist = [] <--TAKE NOTE OF ME!
self.st.add_num(1)
self.st.add_num(2)
self.st.add_num(3)
self.st.add_num(4)
def test_translate(self):
eggs = SpamTest([2, 3, 4, 5])
self.st.incr(1)
self.assertTrue(self.st.__eq__(eggs))
def test_set(self):
nl = [1, 4, 1, 5, 9]
self.st.numlist = nl
self.assertEqual(self.st.numlist, nl)
if __name__ == "__main__":
tests = unittest.TestLoader().loadTestsFromTestCase(Spammer)
unittest.TextTestRunner(verbosity = 2).run(tests)
Run Code Online (Sandbox Code Playgroud)
test_translate的测试失败.
我可以做两件事来让测试成功:
(1)取消注释setUp函数中的第二行.要么,
(2)更改translate首先发生的测试名称.我注意到unittest按字母顺序执行测试.translate例如,更改为atranslate首先执行会使所有测试成功.
对于(1),我无法想象这会如何影响测试,因为在第一行setUp,我们为self.st创建了一个新对象.至于(2),我的投诉是自相似的,哎,对setUp我分配一个新的对象,以self.st使无论我做什么,以self.st在test_set不应该影响的结果test_translate.
那么,我在这里错过了什么?
pep*_*epr 10
如果不研究解决方案的细节,您应该阅读Fredrik Lundh的Python中的默认参数值.
它可能会将您的空列表作为默认参数解释您的问题.原因是该列表仅在第一次为空,除非您稍后明确地将其清空.初始为空的默认列表是列表类型的单个实例,在没有传递显式参数时重用.
阅读上面的文章来修复你对默认参数的思考是个好主意.原因是合乎逻辑的,但可能是意料之外的.
通常建议的修复方法是使用None默认值,__init__如果未传递参数,则在主体内设置空列表,如下所示:
class SpamTest(object):
def __init__(self, numlist=None):
if numlist is None:
numlist = [] # this is the new instance -- the empty list
self.__numlist = numlist
Run Code Online (Sandbox Code Playgroud)