pytest-randomly能暴露测试耦合,因为它通过随机化执行顺序迫使隐性依赖(如全局变量、数据库残留、缓存未清理)在不同组合下显性失败;典型表现是固定seed下特定测试组合报错,换seed后失败用例变化但总在关联组合中出现。

为什么pytest-randomly能暴露测试耦合?
它不直接检测耦合,而是通过打乱执行顺序让隐性依赖浮出水面——如果某个测试总在另一个之后运行才成功,打乱后大概率失败。这种失败不是代码逻辑错,而是测试间共享了状态(比如全局变量、数据库残留、缓存未清理)。
典型现象:pytest 本地跑全绿,加 --randomly-seed=123 后某几个测试报 KeyError 或 AssertionError;换 seed 再跑,失败用例变了,但总在固定组合里出问题。
安装与启用必须做的三件事
- 装插件:
pip install pytest-randomly - 加启动参数:
pytest --randomly-seed=42(固定 seed 才能复现问题) - 禁用默认的模块级 fixture 缓存:
--randomly-dont-reset-seed不要加——它会让每次随机结果不可复现,排查时反而更难
别只加 --randomly-seed 就完事。如果项目用了 pytest-xdist 并行跑,得额外加 --randomly-dont-reset-seed 配合 -n auto,否则子进程 seed 不一致,失败无法定位。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
识别耦合的关键信号和对应检查点
失败时先看错误堆栈顶的测试名,再查它依赖的前一个测试(用 --randomly-seed 多试几次,记下总和它一起失败的其他测试)。重点检查:
- 是否手动修改了
os.environ、sys.path或模块级变量(如requests.adapters.DEFAULT_RETRIES = 0)且没还原 - 是否用了类变量或模块级单例(比如
class Cache: instance = None)而没在setup_method里重置 - 数据库测试是否漏写了
transaction.rollback()或没用@pytest.mark.django_db(reset_sequences=True)(Django 场景) - 是否在
conftest.py里定义了跨文件生效的autouse=Truefixture,且内部有状态变更
修复后验证不能只靠一次成功
改完代码后,必须用至少 3 个不同 seed 跑:pytest --randomly-seed=1、--randomly-seed=2、--randomly-seed=3。单次通过可能是巧合——真正的解耦是无论怎么打乱都稳定通过。
最容易被忽略的是:CI 环境里忘了传 --randomly-seed 参数,或者把插件装在 dev-requirements.txt 但 CI 没装。上线前确认 pip list | grep randomly 和 pytest --help 输出里有 randomly 选项。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










