pytest-check

361 阅读2分钟

pytest-check是一个pytest插件,它允许在一个测试函数中执行多个断言,即使其中一个断言失败,其他断言仍然会被执行。这对于需要执行多个断言的测试场景非常有用,因为它可以在一个测试运行中提供所有失败的断言信息,而不是在第一个失败的断言处停止。

使用pytest-check插件的基本步骤如下:

首先,你需要安装pytest-check插件。你可以使用pip来安装:

pip install pytest-check

然后,你可以在你的测试函数中使用check.equal,check.is_none,check.is_true等函数来执行断言。例如:

from pytest_check import check


def test_example():
    with check:
        check.equal(1, 2)
        check.is_none(None)
        check.is_true(False)

在上述例子中,即使check.equal(1, 2)断言失败,check.is_none(None)和check.is_true(False)仍然会被执行。 这种方式的好处是,你可以在一个测试运行中看到所有失败的断言,而不是在第一个失败的断言处停止。这可以帮助你更快地识别和修复问题。

pytest-check插件的核心实现主要在CheckContextManager类中,这个类定义在context_manager.py文件中。这个类是一个上下文管理器,它的主要功能是在__exit__方法中处理断言错误。 当你在测试函数中使用with check:语句时,你实际上是在创建一个CheckContextManager的实例,并调用它的__enter__和__exit__方法。在__exit__方法中,它会捕获AssertionError异常,并记录失败的断言,而不是立即停止测试函数的执行。 具体来说,当一个断言失败时,会抛出AssertionError异常。在CheckContextManager的__exit__方法中,它会检查异常类型是否为AssertionError。如果是,它会调用log_failure函数来记录失败的断言,并返回True。返回True意味着异常已经被处理,不会再向上抛出,因此测试函数的执行不会被中断,后面的断言仍然会被执行。

以下是CheckContextManager的__exit__方法的代码:

def __exit__(self, exc_type, exc_val, exc_tb):
    __tracebackhide__ = True
    if exc_type is not None and issubclass(exc_type, AssertionError):
        if _stop_on_fail:
            self.msg = None
            return
        else:
            fmt_tb = traceback.format_exception(exc_type, exc_val, exc_tb)
            if self.msg is not None:
                log_failure(f"{exc_val}, {self.msg}", tb=fmt_tb)
            else:
                log_failure(exc_val, tb=fmt_tb)
            self.msg = None
            return True
    self.msg = None