导入test.py后调用pytest.main时conftest钩子未触发的问题求助
解决通过已导入模块调用pytest.main时conftest钩子不触发的问题
问题场景
我需要使用pytest_assertion_pass这类pytest钩子,但测试执行流程受限:
- 必须通过
run_test.py导入test.py并调用execute(),该流程无法修改。run_test.py代码如下:
import test if __name__ == "__main__": test.execute()
- 我在
test.py的execute()中调用pytest.main()执行自身,测试能正常运行,但conftest.py中的钩子函数无法触发。直接在终端执行pytest test.py时钩子能正常工作,但这种方式不可用。
相关代码文件
test.py
import pytest def test_dummy() -> None: assert True def execute() -> None: pytest.main([__file__])
conftest.py
import pytest def pytest_assertion_pass(item: pytest.Item, lineno: int, orig: str, expl: str) -> None: """处理断言通过的钩子,需在pytest.toml中开启enable_assertion_pass_hook = true""" raise ValueError("Assertion pass hook is not implemented yet.")
pytest.toml
[pytest] enable_assertion_pass_hook = true
问题原因
当run_test.py导入test.py时,test模块已被加载到Python的sys.modules字典中。后续在execute()里调用pytest.main()时,pytest发现test模块已存在,会直接使用已加载的模块实例,不会重新从文件读取并处理完整的导入上下文,导致conftest.py中的钩子注册流程未被触发。
解决方案
在test.py的execute()函数中,先从sys.modules中移除已加载的test模块,强制pytest重新从文件导入test.py,即可正常加载conftest.py的钩子:
修改后的test.py:
import pytest import sys def test_dummy() -> None: assert True def execute() -> None: # 移除已加载的test模块,让pytest重新导入 if 'test' in sys.modules: del sys.modules['test'] pytest.main([__file__])
验证:运行run_test.py后,断言通过时会触发pytest_assertion_pass钩子并抛出ValueError,说明钩子已生效。
内容的提问来源于stack exchange,提问作者schussda
相关产品推荐
相关产品推荐

