Python中如何在unittest断言失败时触发另一个方法函数?

在做自动化脚本开发,使用的 unittest 框架, 想在断言失败的时候截图。下面这个例子无论成功或失败都会触发指定的函数,请问怎么修改,只在失败的时候触发函数呢?

import unittest
class loginTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        pass
@classmethod
def tearDownClass(cls):
    pass

def aaa(self):
    print('触发函数')

def test1(self):
    i =2
    self.assertEqual(i,1,self.aaa())

if name == ‘main’: unittest.main()


Python中如何在unittest断言失败时触发另一个方法函数?

3 回复

unittest里,断言失败会直接抛出AssertionError异常,导致测试方法立即停止。如果你想在断言失败后还能执行一些清理或记录操作,标准的做法是使用try...except块来捕获这个异常。

这里有个例子,展示了怎么在断言失败后调用一个自定义的on_assert_fail方法:

import unittest

class TestExample(unittest.TestCase):
    
    def on_assert_fail(self, message):
        """断言失败后触发的自定义方法"""
        print(f"断言失败了,信息是: {message}")
        # 这里可以放你的逻辑,比如记录日志、清理资源等
        # self.cleanup()
    
    def test_something(self):
        a = 5
        b = 10
        custom_msg = "a 应该等于 b"
        
        try:
            self.assertEqual(a, b, msg=custom_msg)
        except AssertionError as e:
            # 捕获到断言异常,先调用我们的自定义方法
            self.on_assert_fail(str(e))
            # 然后重新抛出异常,让unittest框架知道测试失败了
            raise

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

核心思路:

  1. 把可能失败的断言(比如 self.assertEqual)包在 try 块里。
  2. except AssertionError 块中,调用你的自定义函数(比如 on_assert_fail),并把错误信息传给它。
  3. 关键一步:在自定义方法执行完后,用 raise 把捕获到的异常原样抛出。这样 unittest 框架才能正确地将这次测试标记为“失败”(FAILED),而不是“出错”(ERROR)。如果你不重新抛出,测试会被错误地认为是“通过”的。

另一种更通用的写法(使用上下文管理器或装饰器): 如果很多测试方法都需要这个功能,写一堆 try...except 太麻烦。可以定义一个装饰器,这样代码更干净:

import unittest
import functools

def catch_assert_and_call(func):
    """装饰器:在断言失败后调用实例的 on_assert_fail 方法"""
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except AssertionError as e:
            if hasattr(self, 'on_assert_fail'):
                self.on_assert_fail(str(e))
            raise
    return wrapper

class TestExampleWithDecorator(unittest.TestCase):
    
    def on_assert_fail(self, message):
        print(f"[装饰器版] 断言失败: {message}")
    
    @catch_assert_and_call
    def test_with_decorator(self):
        self.assertEqual(1, 2, msg="1 应该等于 2")

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

总结:用 try…except 捕获 AssertionError,执行你的方法后再把异常抛出去。


try:
self.assertEqual(i,1)
except AssertionError as e:
self.aaa
self.assertEqueal(i,1)

你可以试试看。但是如果只做异常处理,这条用例会被认为正确执行了。

我是在 teardown 里判断用例是否执行失败,失败就截图

回到顶部