You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

导入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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 16:33:19