【问题标题】:How to fail a python unittest if the setUpClass throws exception如果 setUpClass 抛出异常,如何使 python 单元测试失败
【发布时间】:2012-08-15 20:39:42
【问题描述】:

我在使用 python setUpClass 时遇到了一点问题。

例如考虑以下情况

class MyTest(unittest.case.TestCase):

    @classmethod
    def setUpClass(cls):
        print "Test setup"
        try:
            1/0
        except:
            raise

    @classmethod
    def tearDownClass(cls):
        print "Test teardown"

几个问题

  1. 上面的代码是处理测试setUpClass异常的正确方法吗(通过提高它以便python unittest可以处理它),有fail(),skip()方法,但只能是由测试实例而不是测试类使用。

  2. 当出现setUpClass异常时,如何保证tearDownClass运行(unittest不运行,要手动调用)。

【问题讨论】:

  • except: raise 什么都不做。 (除了可能会弄乱堆栈跟踪,不确定。)您不妨将整个 try..except 屏蔽掉。
  • 第二个问题:如果您认为您可能会引发异常,那么您应该使用try..except(就像您拥有的那样)在异常上调用tearDownClass。之后,您可以重新引发异常。
  • 感谢您的回复,正如 Jeff 所提到的,调用 tearDownClass 并引发异常的第二种方法是解决方案。
  • @millimoose,它不会弄乱堆栈跟踪。这就是 raise 的意义所在。

标签: python unit-testing


【解决方案1】:

您可以在 Jeff 指出的异常上调用 tearDownClass,但您也可以实现 __del__(cls) 方法:

import unittest

class MyTest(unittest.case.TestCase):

    @classmethod
    def setUpClass(cls):
        print "Test setup"
        try:
            1/0
        except:
            raise

    @classmethod
    def __del__(cls):
        print "Test teardown"

    def test_hello(cls):
        print "Hello"

if __name__ == '__main__':
    unittest.main()

会有以下输出:

Test setup
E
======================================================================
ERROR: setUpClass (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "my_test.py", line 8, in setUpClass
    1/0
ZeroDivisionError: integer division or modulo by zero

----------------------------------------------------------------------
Ran 0 tests in 0.000s

FAILED (errors=1)
Test teardown

注意:您应该知道__del__ 方法将在程序执行结束时被调用,如果您有多个测试类,这可能不是您想要的。

希望对你有帮助

【讨论】:

    【解决方案2】:

    最好的选择是为调用 tearDownClass 和 re-raise 异常的异常添加处理程序。

    @classmethod
    def setUpClass(cls):
        try:
            super(MyTest, cls).setUpClass()
            # setup routine...
        except Exception:  # pylint: disable = W0703
            super(MyTest, cls).tearDownClass()
            raise
    

    【讨论】:

      【解决方案3】:
      import contextlib
      
      class MyTestCase(unitest.TestCase):
      
          @classmethod
          def setUpClass(cls):
              with contextlib.ExitStack() as stack:
                  # ensure teardown is called if error occurs
                  stack.callback(cls.tearDownClass)
      
                  # Do the things here!
      
                  # remove callback at the end if no error found
                  stack.pop_all()
      

      【讨论】:

        【解决方案4】:

        使用 tearDownModule。它应该在 setUpClass 运行后调用。

        【讨论】:

          猜你喜欢
          • 2013-01-23
          • 1970-01-01
          • 1970-01-01
          • 2012-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-30
          • 1970-01-01
          相关资源
          最近更新 更多