pytest-check支持单测试多断言且失败不中断,但需显式调用check.equal()等函数,不能替代assert;安装后导入使用,混用assert会退化为原生行为。

pytest-check 允许你在单个测试函数里执行多个断言,且失败后不立即中断,而是继续运行并汇总所有失败项——但它的行为和原生 assert 不同,必须显式调用检查函数,不能直接替换 assert 语句。
安装与基础用法:确保 pytest-check 正确导入并调用函数
pytest-check 不是 pytest 内置模块,需单独安装;它不提供装饰器或上下文管理器式语法,所有断言都得通过函数调用完成,比如 check.equal()、check.is_true() 等。
- 运行
pip install pytest-check安装(兼容 Python 3.10+) - 在测试文件顶部导入:
from pytest_check import check - 不能写
assert a == b,必须改写为check.equal(a, b)或check.is_true(condition) - 如果混用原生
assert,一旦失败仍会中断执行,失去“多断言收集”效果
常见断言函数对比:哪些能用、参数怎么传、返回值是否可忽略
check 提供的函数名接近 unittest 风格,但全部无返回值、不抛异常(失败时只记录),因此调用后无需 if 判断或赋值。
-
check.equal(actual, expected, msg=None):最常用,等价于assert actual == expected -
check.is_true(expr, msg=None):检查布尔表达式,注意不是check.true(expr) -
check.is_in(item, container, msg=None):替代assert item in container -
check.greater(a, b)、check.less_equal(x, y)等数值比较函数,参数顺序固定,别颠倒 - 所有函数的
msg参数是字符串,不支持格式化表达式(如不能写f"{a} != {b}"),建议提前拼好
错误信息聚合逻辑:为什么有些失败没出现在最终报告里?
pytest-check 默认只在测试函数退出时统一报错,但前提是该函数被识别为“check 测试”——它依赖 pytest 的收集机制,对函数签名和导入方式敏感。
- 测试函数名必须以
test_开头,且不能带@pytest.mark.parametrize以外的装饰器(例如@unittest.skip会破坏收集) - 若测试中调用了未导入的
check.xxx(比如拼错成chech.equal),Python 报NameError,此时 pytest 按异常终止,不会进入 check 汇总流程 - pytest 5.4+ 默认启用
--tb=short,可能折叠 check 失败详情;加--tb=auto或--tb=long才能看到完整失败列表 - 每个失败项独立计数,但整个测试仍算作“1 个用例失败”,终端输出末尾会显示类似
Failed Checks: 3
与 pytest 原生机制共存时的关键限制
pytest-check 本质是绕过 Python 的异常传播链,因此和部分 pytest 特性存在冲突,尤其在 fixture 和作用域控制上。
- 不能在
setup_method、teardown_class等 unittest 风格方法中使用 —— 它只支持纯函数式测试 - 如果测试函数里有
yield(用于生成 fixture),pytest-check 无法工作,会报GeneratorExit或静默跳过检查 - 与
pytest.raises()不兼容:不能在with pytest.raises(...)块内使用check.xxx,否则异常被捕获后 check 记录失效 - 日志和覆盖率工具(如 pytest-cov)能正常统计代码行,但不会标记 check 调用行为本身为“已覆盖”
真正要注意的是:pytest-check 的“不中断”只针对它自己的函数调用;只要混入任意一个原生 assert 或未捕获异常,整个流程就退回到标准 pytest 行为。所以检查是否生效,最简单的办法是故意让第一个 check.equal() 失败,再看后续 check 是否仍执行并被报告。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











