Python3 unittest测试受前序测试值污染问题求助
测试用例互相干扰问题排查与解决
问题场景
使用Python 3 unittest时遇到测试用例互相干扰的问题,简化后的代码与测试场景如下:
Try类代码
class Try: def __init__(self,xa=[]): self.XA = xa def getCount(self): return len(self.XA) @classmethod def newAfter(cls,arrayA): localo = cls() localo.pushX(arrayA[0]) return localo def pushX(self,xFloat): self.XA.append(xFloat)
测试用例代码
#!/usr/bin/python3 # test_1_Try.py import unittest import Try as tr class Test_Try(unittest.TestCase): def test_Constructs_with_no_argument(self): localo = tr.Try() self.assertIsInstance( localo, tr.Try ) localo.pushX(5.333) def test_newAfter(self): localo = tr.Try.newAfter(["1.5"]) self.assertEqual(1,localo.getCount()) if __name__ == '__main__': unittest.main()
执行测试的错误输出
$ ./test_1_Try.py .F ====================================================================== FAIL: test_newAfter (__main__.Test_Try) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/nsdd/shop/sames/statistics1v/bugdir/./test_1_Try.py", line 17, in test_newAfter self.assertEqual(1,localo.getCount()) AssertionError: 1 != 2 ---------------------------------------------------------------------- Ran 2 tests in 0.000s
额外现象
- 移除第一个测试,仅运行第二个测试可正常通过
- 保留两个测试并在
test_newAfter中添加断言self.assertEqual("1.5",localo.XA[0]),会得到错误AssertionError: '1.5' != 5.333
问题根源
这是Python中可变对象作为默认参数的经典陷阱:当__init__方法将xa=[]设为默认参数时,这个空列表会在类定义阶段被创建一次,之后所有不传入xa参数的Try()实例都会共享这同一个列表对象。第一个测试中调用pushX(5.333)修改了这个共享列表,第二个测试里newAfter方法创建的实例仍使用这个已被修改的列表,导致测试数据残留,出现用例干扰。
解决方案
修改Try类的__init__方法,避免直接使用可变对象作为默认参数,改用None作为默认值,在方法内部初始化空列表:
class Try: def __init__(self, xa=None): # 当xa为None时,创建新的空列表,避免共享 self.XA = xa if xa is not None else [] def getCount(self): return len(self.XA) @classmethod def newAfter(cls, arrayA): localo = cls() localo.pushX(arrayA[0]) return localo def pushX(self, xFloat): self.XA.append(xFloat)
修改后,每次调用Try()(不传入参数)都会生成新的空列表,各个实例的XA相互独立,测试用例之间不再互相干扰。
验证结果
重新运行测试用例,两个测试均正常通过:
$ ./test_1_Try.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
内容的提问来源于stack exchange,提问作者user3713271
相关产品推荐
相关产品推荐

