You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 18:44:56