Python unittest测试疑问:为何未定义属性赋值后测试可正常通过
Why does the second unittest pass while the first fails with an AttributeError?
我正在使用Python的unittest模块学习单元测试,遇到了一个奇怪的现象。请参考以下代码:
import unittest class Foo: pass class FooTest(unittest.TestCase): def test_non_existent_property(self): foo = Foo() self.assertTrue(0, len(foo.class_name)) def test_assigning_name(self): foo = Foo() foo.class_name = 'bar' self.assertEqual('bar', foo.class_name) unittest.main()
测试结果如下:
ERROR: test_non_existent_property (__main__.FooTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "<pyshell#28>", line 4, in test_non_existent_property AttributeError: 'Foo' object has no attribute 'class_name' ---------------------------------------------------------------------- Ran 2 tests in 0.037s FAILED (errors=1)
第一个测试按预期失败,但第二个测试却通过了,这让我感到困惑。它难道不应该也失败吗?请问这是为什么?
这其实是Python作为动态编程语言的特性,再加上unittest测试方法的独立性共同导致的,咱们一步步拆解清楚:
测试方法是完全独立的
你写的两个测试方法test_non_existent_property和test_assigning_name是完全隔离的执行单元。每个方法里的foo = Foo()都会创建一个全新的Foo实例,两个实例之间没有任何关联——第一个测试里的实例有没有属性,完全不影响第二个测试里的新实例。Python支持动态添加对象属性
在第二个测试中,你先执行了foo.class_name = 'bar',这一步本质是给当前这个foo实例动态新增了一个名为class_name的属性,并把它的值设为'bar'。之后你用self.assertEqual('bar', foo.class_name)去断言,自然能取到这个刚赋值的属性,断言成立,测试也就通过了。
而第一个测试里,你直接尝试访问foo.class_name,这个实例从来没有被赋予过这个属性,所以触发了AttributeError,测试报错失败,这完全符合预期。
简单总结:第二个测试不是“访问原本不存在的属性”,而是先给实例新增属性,再去访问,所以没问题;两个测试的实例是完全分开的,互不影响。
内容的提问来源于stack exchange,提问作者Jack Griffin
相关产品推荐
相关产品推荐

