pytest-watch 默认不重试失败用例,因其设计目标仅为文件变更后触发全新 pytest 进程,不介入测试结果判断;重试属 pytest 运行时策略,须由 pytest-rerunfailures 等插件在单次执行内实现,无法跨轮次继承失败状态。

pytest-watch 本身不支持“保存后自动重试失败用例”——它只支持保存后重新运行全部或匹配的测试,重试需额外封装逻辑。
为什么 pytest-watch 默认不重试失败用例?
pytest-watch 的设计目标是“文件变更 → 触发 pytest 执行”,它把控制权完全交给 pytest,自身不介入测试结果判断。重试(retry)属于测试执行策略,需 pytest 插件(如 pytest-rerunfailures)在 pytest 运行时介入,而 pytest-watch 启动的是全新 pytest 进程,不会继承上一轮的失败状态。
如何让保存后只重跑上次失败的用例?
靠 pytest-watch 自身做不到,但可通过组合 --lf(last-failed)参数 + 正确的 pytest 配置实现近似效果:
-
pytest-watch --on-failure "echo 'failed'; pytest --lf"不可靠:--on-failure 在 watch 进程级触发,不是每次 pytest 子进程失败都调用 - 正确做法是让 pytest-watch 总是调用
pytest --lf --tb=short,并确保 pytest 能持久化失败记录 - 启用
--lf前必须先跑一次完整测试(生成.pytest_cache/v/cache/lastfailed) - 若用
pytest-xdist并行执行,--lf可能漏掉部分失败项,建议开发期禁用 xdist
怎样配合 pytest-rerunfailures 实现“失败自动重试”?
注意:rerun 是单次 pytest 运行内的行为,不是跨轮次重试。想在保存后自动对失败用例做 2 次重试,需这样配置:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
立即学习“Python免费学习笔记(深入)”;
- 安装插件:
pip install pytest-rerunfailures - 在
pytest.ini中写入:[tool:pytest] reruns = 2 reruns-delay = 1
- 再用 pytest-watch 启动:
pytest-watch --on-py-change "pytest --lf --reruns 2" - ⚠️ 关键点:
--lf和--reruns可共存,但--lf决定“跑哪些用例”,--reruns决定“每个失败用例重试几次” - 如果某用例在重试后仍失败,它会进入下一轮
--lf的候选列表
常见陷阱和绕不开的细节
实际用起来容易卡在几个地方:
- 缓存路径权限问题:
.pytest_cache若被 gitignore 或 IDE 清理,--lf就失效;建议在.gitignore中保留!.pytest_cache/v/cache/lastfailed - pytest-watch 的
--runner参数比--on-py-change更稳定,推荐写成:pytest-watch --runner "pytest --lf --reruns 2" - 修改 conftest.py 或 fixture 时,
--lf不会自动清空缓存,需手动删.pytest_cache或加--cache-clear - Windows 下 PowerShell 对引号和空格处理敏感,
--on-py-change命令建议用 cmd.exe 或直接写脚本封装
真正要“保存即重试失败项”,核心不在 watch 工具,而在理解 pytest 的缓存机制和 rerun 插件的生效边界——它只管本轮,不管上轮;只管标记,不管记忆。

















