Python unittest如何实现测试用例间的属性隔离
问题原因
核心逻辑非常直接:unittest 为了实现测试间状态隔离,不会复用同一个测试类实例运行所有测试方法。
你对普通Python类的属性查找逻辑理解没有错,但默认的前提「两个测试方法是在同一个类实例上调用的」,在unittest的运行机制里完全不成立:
- 整个测试流程中,
setUpClass只会在所有测试启动前执行一次,给DummyTestCase类本身绑定类属性foo = 42,这个类属性在你给出的示例代码里全程没有被修改过。 - 每一个
test_前缀的测试方法执行前,框架都会重新实例化一次DummyTestCase,生成一个全新的实例对象。test_1和test_2运行时拿到的self是两个完全独立、互不关联的对象,单个测试方法运行结束后,对应的实例就会被销毁,实例上的所有属性修改都会被回收。
拆解代码中self.foo += 1的执行步骤,就能完全对应上你看到的输出:
- 运行
test_1阶段:- 框架创建第一个实例
inst1,此时inst1自身没有绑定foo属性 - 执行
self.foo += 1:先通过属性查找链找到类属性foo=42,计算加1得到43,再给inst1自身绑定实例属性foo=43,最终打印43 test_1执行完成,inst1被销毁,它身上的实例属性修改也随之清除
- 框架创建第一个实例
- 运行
test_2阶段:- 框架创建第二个全新的实例
inst2,此时inst2自身也没有绑定foo属性 - 执行
self.foo += 1:还是找到类层面从未被改动的foo=42,计算加1得到43,给inst2自身绑定实例属性foo=43,最终打印43 test_2执行完成,inst2被销毁
- 框架创建第二个全新的实例
你可以在两个测试方法里加一行print(id(self))自行验证,两次打印的实例内存地址完全不同,根本不是同一个对象。
如果确实需要让属性修改在测试间共享,需要显式修改类属性,比如写type(self).foo += 1,但这种做法会破坏测试隔离性,导致测试结果受用例执行顺序影响,绝大多数场景下都不推荐使用。
内容的提问来源于stack exchange,提问作者Weier
相关产品推荐
相关产品推荐

