混用 pytest 和 unittest 极易触发 fixture 加载失败、测试发现混乱、执行顺序失控三类问题,根本原因是二者生命周期管理机制不兼容;conftest.py 中的 fixture 对 unittest.testcase 完全无效,因其绕过 pytest 的注入流程。

混用 pytest 和 unittest 不会自动报错,但实际运行时极易触发 fixture 加载失败、测试发现混乱、执行顺序失控三类问题——根本原因是两个框架的生命周期管理机制不兼容,不是“能跑通”就等于“安全可用”。
conftest.py 中的 fixture 在 unittest 测试里根本不会生效
pytest 的 conftest.py 仅对 pytest 发现的测试函数/类起作用;unittest.TestCase 子类完全绕过 pytest 的 fixture 注入流程。常见错误现象是:TypeError: test_something() missing 1 required positional argument: 'db',而你明明在 conftest.py 里写了 @pytest.fixture。
- 别试图用
pytest.main()包裹unittest.TestLoader—— 这会导致 fixture 初始化被跳过 - 如果必须保留旧的
unittest用例,改用setUpClass/tearDownClass手动模拟 fixture 行为,而不是依赖conftest.py -
pytest启动时加--tb=short能更快暴露这类“参数缺失”错误,避免误判为逻辑 bug
pytest 先运行再跑 unittest 会引发 import 缓存污染
当 pytest 加载过某个模块(比如 numpy 或自定义的 utils),再由 unittest 的 TestLoader 重新导入同一模块时,Python 的 sys.modules 缓存可能残留旧状态。典型表现是:AttributeError: module 'xxx' has no attribute 'y',但单独运行 unittest 时完全正常。
- 强制清空缓存不可靠,更稳妥的做法是:用不同进程隔离运行,例如
python -m pytest tests/pytest_style/ && python -m unittest discover -s tests/unittest_style/ - 避免在
__init__.py或conftest.py中做全局 import 副作用(如 patch、monkeypatch),这些操作会污染后续unittest进程 - CI/CD 中务必用
python -m pytest --collect-only验证 pytest 是否真能发现你预期的测试,防止“看似跑完实则漏掉”
混合项目里 pip install 后 pytest 版本升级导致 unittest 失效
某些 pytest 插件(如 pytest-asyncio)或新版 pytest 本身会修改 unittest 的默认行为,比如重写 TestCase.run()。错误现象包括:测试用例静默跳过、setUp 不执行、断言失败却不报错。
- 检查
pip list | grep pytest,若版本 ≥ 8.0,回退到pytest==7.4.4(该版本对unittest兼容性最稳定) - 在
setup.cfg或pyproject.toml中显式锁定:requires = pytest,防止 <code>pip install -e .意外升级 - 不要在
pytest.ini中启用addopts = --reuse-db类选项,它会让unittest的数据库 setup 彻底失效
真正麻烦的不是“怎么让它们一起跑”,而是“怎么让它们不互相干扰”。只要项目里还存在 unittest.TestCase,就别指望 conftest.py 或 pytest_plugins 对它起效——这是设计使然,不是配置没调好。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











