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

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测试方法的独立性共同导致的,咱们一步步拆解清楚:

  1. 测试方法是完全独立的
    你写的两个测试方法test_non_existent_property和test_assigning_name是完全隔离的执行单元。每个方法里的foo = Foo()都会创建一个全新的Foo实例,两个实例之间没有任何关联——第一个测试里的实例有没有属性,完全不影响第二个测试里的新实例。

  2. Python支持动态添加对象属性
    在第二个测试中,你先执行了foo.class_name = 'bar',这一步本质是给当前这个foo实例动态新增了一个名为class_name的属性,并把它的值设为'bar'。之后你用self.assertEqual('bar', foo.class_name)去断言,自然能取到这个刚赋值的属性,断言成立,测试也就通过了。

而第一个测试里,你直接尝试访问foo.class_name,这个实例从来没有被赋予过这个属性,所以触发了AttributeError,测试报错失败,这完全符合预期。

简单总结:第二个测试不是“访问原本不存在的属性”,而是先给实例新增属性,再去访问,所以没问题;两个测试的实例是完全分开的,互不影响。

内容的提问来源于stack exchange,提问作者Jack Griffin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:12:46