pytest默认不显示DeprecationWarning,因Python解释器默认忽略该警告;需通过-W default::DeprecationWarning显式启用,推荐配置在pyproject.toml或命令行中。

pytest运行时为什么看不到DeprecationWarning
默认情况下,Python会忽略DeprecationWarning(除非由__main__模块直接触发),所以即使代码里调用了已弃用的函数,pytest也不会报出来。这不是pytest的问题,是Python解释器的警告过滤策略在起作用。
实操建议:
- 必须显式启用
DeprecationWarning,不能依赖pytest默认行为 - 推荐用
-W default::DeprecationWarning,而不是-W error::DeprecationWarning——后者会让测试直接失败,不利于渐进式清理 - 如果项目用
pyproject.toml,可在[tool.pytest.ini_options]下加filterwarnings = ["default::DeprecationWarning"],效果等同于命令行-W
用-W参数捕获DeprecationWarning的正确写法
-W是Python解释器参数,不是pytest专属,所以要确保它传给了Python进程本身。常见错误是把-W放在pytest命令之后,导致被pytest当成自己的选项而忽略。
正确写法(两种等效方式):
立即学习“Python免费学习笔记(深入)”;
python -W default::DeprecationWarning -m pytest-
pytest -W default::DeprecationWarning(pytest 6.0+ 支持透传给Python)
注意:default表示“按默认规则显示”,ignore/error/always是其他常用动作;::DeprecationWarning中的双冒号分隔动作、类别和模块名,类别必须精确匹配。
为什么有些DeprecationWarning还是不出现
常见原因不是参数没加对,而是警告源头被第三方库或测试框架提前捕获/压制了。
排查步骤:
- 检查是否在
conftest.py或pytest_configure里调用了warnings.filterwarnings("ignore", category=DeprecationWarning) - 某些库(如
numpy、scipy)会在导入时主动filterwarnings("ignore"),需在pytest.ini或命令行中用-W覆盖其设置 - 确认警告确实来自你关心的模块:在疑似位置手动触发
warnings.warn("test", DeprecationWarning),看是否能被捕获,排除环境配置问题
把过期代码警告集成进CI流程
只在本地跑不够,得让CI也守住这道线。关键是让警告变成可检测的输出,而非仅靠人眼扫日志。
实操建议:
- 用
pytest --tb=short -W error::DeprecationWarning作为CI阶段的“硬性检查”,一旦出现就中断构建(适合清理收尾阶段) - 用
pytest -W always::DeprecationWarning --capture=no 2>&1 | grep "DeprecationWarning"提取警告行做计数,配合|| true避免管道失败中断,再用脚本判断数量是否超阈值 - 注意:CI环境Python版本可能比本地高,某些在旧版不报的弃用行为(如
asyncio.async)在新版会触发,需保持CI Python版本与目标兼容版本一致
真正难的不是让警告出来,而是区分哪些是自己写的过期逻辑、哪些是上游库还没升级导致的噪音——得结合stacklevel和调用栈定位源头,否则容易误伤。


















