最可靠的方式是组合判断:优先检查 "pytest" in sys.modules,其次 fallback 到 os.environ.get("PYTEST_RUNNING") == "1",必要时用 inspect.stack() 追溯调用栈;需注意执行时机差异。

检查 sys.argv 中是否包含 pytest 相关参数
pytest 启动时通常会在 sys.argv 开头插入自身路径,后续可能带 -x、--tb=short 等标志;但仅靠参数不可靠——用户可能手动运行脚本并传入类似参数。更稳妥的做法是结合多个信号判断。
- 检查
sys.argv[0]是否以pytest或py.test结尾(注意跨平台路径分隔符) - 避免误判:有些 IDE(如 PyCharm)会把测试入口包装成临时脚本,此时
argv[0]是 IDE 生成的路径,而非pytest - 可补充检查
"pytest" in sys.modules,但需注意:pytest 模块未必已完全初始化,尤其在 conftest.py 执行早期
检测 pytest 是否已在 sys.modules 中注册
pytest 在启动过程中会提前将自身模块注入 sys.modules,哪怕还没执行到测试函数。这个检查比解析命令行更稳定,且开销极小。
- 用
"pytest" in sys.modules判断即可,无需导入pytest(否则可能触发意外初始化) - 注意:如果代码在
pytest_configure钩子之前执行(比如顶级 import 时),该检查可能为False,属于正常时序问题 - 某些打包工具(如 PyInstaller)可能干扰
sys.modules,此时需 fallback 到其他方式
通过 os.environ 检查 pytest 特有环境变量
pytest 本身不设置标准环境变量,但常用插件(如 pytest-xdist)会注入 PYTEST_XDIST_WORKER,而 CI 环境中常由 wrapper 脚本设 PYTEST_RUNNING=1。这不是 pytest 原生行为,但实践中很常见。
- 检查
os.environ.get("PYTEST_RUNNING") == "1"是最轻量的协作式方案 - 不建议依赖
PYTEST_XDIST_WORKER单独判断,因为单进程运行时它不存在 - 若项目可控,推荐在
pytest.ini的addopts中加--env=PYTEST_RUNNING=1,再配合pytest-env插件传播
用 inspect.stack() 追溯调用栈是否含 pytest 框架路径
这是兜底方案,适用于上述方法都失效的边缘场景(如嵌入式测试、自定义 runner)。原理是看当前帧的上层是否来自 pytest 的 _pytest/ 或 py/_ 路径。
- 示例判断逻辑:
any("pytest" in frame.filename or "_pytest" in frame.filename for frame in inspect.stack()) - 性能较差,不应在热路径(如模型 forward 方法)中调用
- 注意:Python 3.12+ 对
inspect.stack()的开销做了优化,但仍比前几种方式重一个数量级 - 容易漏判:pytest 可能被重命名或从 zip 包加载,导致
frame.filename不含明显关键词
conftest.py 导入阶段、测试函数内部、fixture 初始化时,可用的上下文信号完全不同。别只依赖单一条件。










