【问题标题】:Why isn't assertRaises catching my Attribute Error using python unittest?为什么 assertRaises 不使用 python unittest 捕获我的属性错误?
【发布时间】:2010-11-19 10:20:48
【问题描述】:

我正在尝试运行这个测试:self.assertRaises(AttributeError, branch[0].childrennodes)branch[0] 没有属性 childrennodes,所以它应该抛出一个 AttributeErrorassertRaises 应该捕获它,但是当我运行测试,测试失败,因为它正在抛出 AttributeError

Traceback (most recent call last):
  File "/home/tttt/../tttt/tests.py", line 504, in test_get_categories_branch
    self.assertRaises(AttributeError, branch[0].children_nodes)
AttributeError: 'Category' object has no attribute 'children_nodes'

有什么想法吗?

【问题讨论】:

    标签: python django unit-testing


    【解决方案1】:

    当测试运行时,在调用 self.assertRaises 之前,Python 需要找到所有方法参数的值。这样做时,它会评估 branch[0].children_nodes,这会引发 AttributeError。由于我们还没有调用 assertRaises,所以这个异常没有被捕获,导致测试失败。

    解决方案是将branch[0].children_nodes 包装在一个函数或一个 lambda 中:

    self.assertRaises(AttributeError, lambda: branch[0].children_nodes)
    

    assertRaises 也可以用作上下文管理器(从 Python 2.7 开始,或在 PyPI 包 'unittest2' 中):

    with self.assertRaises(AttributeError):
        branch[0].children_nodes
        # etc
    

    这很好,因为它可以在测试过程中用于任意代码块,而不必创建一个新函数来定义它适用的代码块。

    如果需要,它可以让您访问引发的异常以进行进一步处理:

    with self.assertRaises(AttributeError) as cm:
        branch[0].children_nodes
    
    self.assertEquals(cm.exception.special_attribute, 123)
    

    【讨论】:

      【解决方案2】:

      我认为这是因为 assert raises 只接受一个可调用的。它评估可调用对象是否引发异常,而不是语句本身是否引发异常。

      self.assertRaises(AttributeError, getattr, branch[0], "childrennodes")
      

      应该可以。

      编辑:

      正如 THC4k 正确所说,它在收集时收集语句,然后会出错,而不是在测试时。

      这也是我喜欢鼻子的一个原因,它有一个装饰器(凸起),对这类测试有用且更清晰。

      @raises(AttributeError)
      def test_1(self)
          branch[0].childrennodes
      

      【讨论】:

      • 这是正确的解决方案,但是当 Python 将参数收集到 self.assertRaises 时会发生异常。它必须在调用函数之前评估branch[0].childrennodes,这会引发异常。
      • unittest 也有类似的功能。我已经在自己的回答中描述了它们。拥抱!
      【解决方案3】:

      pytest 也有类似的装饰器:

      from pytest import raises
      
      def test_raising():
          with raises(AttributeError):
              branch[0].childrennodes
      

      【讨论】:

        猜你喜欢
        • 2017-06-29
        • 2013-07-09
        • 2021-11-22
        • 2012-01-30
        • 2021-01-30
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        • 2019-05-27
        相关资源
        最近更新 更多