pytest-deadfixtures是pytest插件,能精准识别本次运行中完全未被调用的fixture(含function/module/session级及autouse=true的fixture),但不检测条件分支内调用或字符串间接引用的fixture;安装执行pip install pytest-deadfixtures,运行命令为pytest --dead-fixtures。

pytest-deadfixtures 是什么,它能发现哪些 Fixture?
它不是静态分析工具,而是通过实际运行测试来识别未被任何 test_* 函数或其它 fixture 引用的 fixture。它不会报出“可能没用”的 fixture,只报出**在本次 pytest 运行中完全未被调用**的 fixture——包括 @pytest.fixture 定义的函数、autouse=True 的 fixture(如果确实没被触发),以及 session/module/class 级别的 fixture。
注意:它无法检测“只在某些分支路径中被使用”的 fixture(比如被 if 条件包裹的 fixture 调用),因为 pytest 在收集阶段就决定了 fixture 依赖图,而 deadfixtures 基于实际执行路径判断。
安装和基础运行命令怎么写?
直接 pip 安装后就能用,无需额外配置:
pip install pytest-deadfixtures
运行时加 --dead-fixtures 参数即可:
pytest --dead-fixtures
常见组合用法:
- 只检查某个目录:
pytest tests/ --dead-fixtures - 跳过特定 scope 的 fixture(比如忽略 session 级):
pytest --dead-fixtures --dead-fixtures-scope=function - 输出更详细信息(含 fixture 所在文件和行号):
pytest --dead-fixtures -v
默认只报告 function 和 module 级 fixture;session 和 package 级 fixture 需显式指定 --dead-fixtures-scope 才会纳入检查。
为什么有些 fixture 明明写了却没被识别为“dead”?
这是最常困惑的地方——fixture 没被报出来,不代表它有用,可能只是 deadfixtures 没“看到”它被调用。典型原因有:
- fixture 名被字符串形式间接引用:
request.getfixturevalue("my_fixture")—— deadfixtures 不解析字符串,会漏判 - fixture 被
autouse=True但作用域内无测试运行(比如整个 test file 被@pytest.mark.skip跳过)——此时它其实“死”了,但工具因没执行而无法判定 - fixture 定义在 conftest.py 中,但当前 pytest 命令没覆盖到该 conftest 所在目录(比如你只跑
pytest tests/unit/,而 conftest 在tests/上层) - fixture 名与测试函数参数名相同,但被 pytest 的参数注入机制绕过了依赖声明(极少见,多见于旧版 pytest 或自定义 hook)
如何确认一个 reported dead fixture 真的可以删?
报出来的 fixture 不等于“绝对可删”,得人工验证:
- 搜代码库中是否出现
my_fixture字符串(尤其注意字符串引用、文档字符串、注释里的误匹配) - 检查是否被非测试代码 import 使用(比如某些 fixture 也作为工具函数被
utils.py导入) - 确认是否被第三方插件或自定义 pytest hook 间接调用(如
pytest_configure中手动 setup) - 删掉后重新跑全量测试 + 相关 CI 流程,观察是否影响 setup/teardown 行为(比如数据库清理、临时目录创建等 side effect fixture)
特别注意:带 yield 或 addfinalizer 的 fixture,即使没被测试直接依赖,也可能承担全局资源管理职责——这类 fixture 很容易被误判为 dead,但删掉会导致资源泄漏或环境残留。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











