pytest-repeat 的 --count 参数无法稳定复现偶发 Bug,因其在单进程内重复执行、不重置模块状态、不清理全局变量、不启动多进程、不增加内存压力;需组合 --count + --restart=each + pytest-xdist + 清理 fixture + 随机种子控制 + 日志对比 + 时间扰动才能有效暴露问题。

pytest-repeat 能帮你把偶发 Bug 变成稳定可观察的问题,但直接加 --count=100 很可能白跑——关键在控制重试逻辑和隔离干扰。
为什么 pytest --count=10 有时根本复现不了偶发 Bug
默认情况下,pytest-repeat 对每个测试用例做独立重复执行,但没重置模块状态、没清空全局变量、没重启进程。如果 Bug 依赖于某次执行后残留的缓存或文件锁,单纯多跑几次只是在“复现成功路径”。
- 用
--count时,所有重复都在同一个 Python 进程内运行,import缓存、logging配置、单例对象都不会刷新 - 如果 Bug 出现在并发场景(比如两个线程争抢资源),
--count不等于--workers=2,它不启动多进程 - 某些异常(如
ResourceWarning或 GC 触发时机问题)只在特定内存压力下出现,--count不增加内存负载
真正有效的复现策略:组合 --count + --restart + 自定义 fixture
要让每次重复都接近“全新启动”,得绕过 pytest 默认的模块复用机制。官方没提供进程级重启,但可以用 --restart 参数配合 pytest-xdist 模拟:
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 先安装:
pip install pytest-repeat pytest-xdist - 用
pytest test_flaky.py --count=50 --restart=each --numprocesses=1——--restart=each会让每个重复都开新进程(需pytest-xdist>=3.0) - 在测试里加 fixture 强制清理:比如每次运行前删掉临时目录、重置
time.time()模拟器、关闭已打开的 socket - 避免在
setup_module中做一次性初始化;改用autouse=True的函数级 fixture,并在teardown阶段显式清理
如何定位是环境问题还是代码缺陷?用 --randomly-seed 和 --tb=short 缩小范围
偶发 Bug 常和执行顺序、随机数、系统时间相关。光靠重复不够,得控制变量:
立即学习“Python免费学习笔记(深入)”;
- 加
--randomly-seed=12345(需装pytest-randomly)固定随机种子,排除 RNG 导致的非确定性 - 用
--tb=short快速查看失败堆栈,避免被冗长 traceback 淹没;配合--maxfail=1让第一次失败就停住 - 在失败测试里插入
print(f"PID: {os.getpid()}, time: {time.time()}"),确认是不是多进程间共享了不该共享的状态 - 如果 Bug 只在 CI 环境出现,加
--log-cli-level=INFO把日志打出来,对比本地和 CI 的sys.path、os.environ差异
最常被忽略的一点:很多“偶发”其实是 time.sleep(0.1) 类等待不足导致的竞态,而 pytest-repeat 不会自动放大这种时间敏感问题——你得手动在测试里注入延迟扰动,或者用 pytest-timeout 配合超时触发来暴露隐藏的阻塞点。

















