Python Unittest问题:如何确保对象不携带前次运行数据?
测试用例中对象状态未重置的问题:原因与解决方案
你遇到的这个问题,是Python里一个非常经典的可变默认参数陷阱,跟setUp方法本身没关系——setUp确实每次测试前都会创建新的Entity实例,但你的Entity类本身有个设计问题,导致所有无参创建的实例都共享了同一个列表!
问题根源
看你的Entity类定义:
class Entity: def __init__(self, entities = []): self.entities = entities
在Python中,函数/方法的默认参数是在定义时就计算并创建的,而不是每次调用时重新生成。也就是说,这个[]空列表在你定义__init__方法的时候就已经存在了,之后每次调用Entity()(不传入entities参数)时,都会复用这个同一个列表对象。
所以testA里创建的实例和testB里创建的实例,它们的self.entities指向的是同一个列表!testA添加了"Foo"之后,这个列表内容被修改,testB的实例自然会看到这个改动。
修复方法
把默认参数改成None,然后在__init__内部初始化新的空列表,确保每个实例都有自己独立的列表:
class Entity: def __init__(self, entities=None): # 如果没有传入自定义列表,就创建全新的空列表 self.entities = entities if entities is not None else [] def add(self, entity: str): if entity not in self.entities: self.entities.append(entity)
验证结果
修改后再运行测试:
$ python -m unittest discover -v testA (test_entity.EntityTestCase) ... Starting Entites = [] ok testB (test_entity.EntityTestCase) ... Starting Entites = [] ok ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK
现在每个测试用例的Entity实例都有自己的空列表,testA和testB的状态完全独立,测试就能正常通过了。
额外提示
这个可变默认参数的坑很容易中招,记住:永远不要用可变对象(列表、字典、自定义实例等)作为函数/方法的默认参数,如果需要默认的可变值,就用None作为占位符,然后在函数内部创建新的可变对象。
内容的提问来源于stack exchange,提问作者Julio
相关产品推荐
相关产品推荐

