断言失败时Python单元测试调用函数

Ari*_*ury 1 python unit-testing

目标:仅当测试失败时,我才需要调用一堆步骤(因此是一个函数)。

我尝试过的:

1)尝试传递不带参数的函数。

观察:如果测试通过,则不会调用函数。但如果测试失败,我会收到错误消息。(AssertionError: <bound method TestAuto.func1 of <test_fail.TestAuto testMethod=test_fail>>)

class TestAuto(unittest.TestCase):
    def test_fail(self):
        self.assertEqual(1, 1, self.func1)
    def func1(self):
        print 'We are inside'
if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

test_fail (test_fail.TestAuto) ... ok

----------------------------------------
Ran 1 test in 0.001s

OK
Run Code Online (Sandbox Code Playgroud)

2)尝试使用参数调用函数。

class TestAuto(unittest.TestCase):
    def test_fail(self):
        self.assertEqual(1, 1, self.func1('message'))
    def func1(self, msg):
        print msg
Run Code Online (Sandbox Code Playgroud)

观察:无论测试通过或失败,函数都会被调用。

结果:

test_fail (test_fail.TestAuto) ... 消息正常


在 0.001 秒内运行 1 次测试

好的

小智 5

您可以使用序数try/except语句:

from exceptions import AssertionError as AE

class TestAuto(unittest.TestCase):
    def test_not_fail(self):
        # won't call func1
        try:
            self.assertEqual(1, 1)
        except AE:
            self.func1()
            raise

    def test_fail(self):
        # will call func1
        try:
            self.assertEqual(1, 9)
        except AE:
            self.func1()
            raise

    def func1(self):
        print 'We are inside'
Run Code Online (Sandbox Code Playgroud)

可以将其实现为装饰器以方便使用:

from exceptions import AssertionError as AE

def run_if_test_fails(call_on_fail):
    def deco(f):
        def inner(*args, **kwargs):
            try:
                f(*args, **kwargs)
            except AE:
                # test failed - run callback
                call_on_fail()
                # reraise Error to mark it in result
                raise
        return inner
    return deco

def func1():
    print('We are inside')

class TestAuto(unittest.TestCase):

    @run_if_test_fails(func1)
    def test_not_fail(self):
        # won't call func1
        self.assertEqual(1, 1)

    @run_if_test_fails(func1)
    def test_fail(self):
        # will call func1
        self.assertEqual(1, 9)
Run Code Online (Sandbox Code Playgroud)