如何正确使用pytest_assertion_pass钩子统计所有通过的断言
问题
在pytest中尝试统计所有通过的断言数量,启用pytest_assertion_pass钩子后,仅统计到5个通过的断言,但实际有43个测试用例(每个至少包含一个断言)。进一步排查发现:直接写在test函数内的assert会被统计,但封装在自定义断言函数(如assert_equal)里的assert不会触发钩子。
相关配置与代码
pytest.ini
[pytest] enable_assertion_pass_hook=true
conftest.py
assertion_count = 0 def pytest_assertion_pass(item, lineno, orig, expl): global assertion_count assertion_count += 1 def pytest_terminal_summary(terminalreporter, exitstatus, config): print(f'\n{assertion_count} assertions tested.')
输出结果
platform linux -- Python 3.10.6, pytest-7.3.1, pluggy-1.0.0 rootdir: /home/user/project configfile: pytest.ini plugins: cov-4.1.0 collected 43 items az/test/colours_test.py ............................... [ 72%] az/test/logging_test.py ............ [100%] 5 assertions tested.
原因分析
这是因为pytest的断言钩子机制基于代码重写实现,存在范围限制:
- pytest仅会在测试收集阶段,对test函数/测试类方法内部的
assert语句进行动态重写,注入pytest_assertion_pass钩子的触发逻辑; - 自定义断言函数不属于test函数的直接代码块,pytest不会对这类函数内部的
assert执行重写操作,因此这些断言通过时不会触发钩子,自然不会被统计。
简单说,只有直接写在测试函数/方法内的assert会被pytest处理并触发统计,封装在其他函数里的assert不在pytest的重写范围内,无法被钩子捕获。
内容的提问来源于stack exchange,提问作者David Gard
相关产品推荐
相关产品推荐

