pytest-rerunfailures 是 pytest 插件,用于重试因环境抖动导致的偶发性失败测试,不解决逻辑错误;支持命令行、配置文件及 @pytest.mark.flaky 装饰器三种配置方式。

pytest-rerunfailures 是什么,能解决什么问题
pytest-rerunfailures 是 pytest 的一个插件,专门用来重试失败的测试用例。它不改变测试逻辑,只在用例执行失败后自动按指定次数重新运行——适合处理那些因环境抖动(如网络超时、数据库连接短暂中断、UI 元素加载延迟)导致的偶发性失败,而不是代码逻辑错误。
它不能帮你修复 AssertionError 或 TypeError 这类稳定复现的问题;如果一个用例每次运行都失败,重试只会浪费时间并掩盖真实缺陷。
安装和基础命令行用法
确保已安装 pytest 后,直接 pip 安装插件:
pip install pytest-rerunfailures
最常用方式是通过命令行参数控制重试行为:
立即学习“Python免费学习笔记(深入)”;
-
--reruns 3:每个失败用例最多重试 3 次(共运行 4 次,含首次) -
--reruns-delay 1:每次重试前等待 1 秒(避免密集重试压垮服务) -
--only-rerun "ConnectionRefusedError|TimeoutError":只对匹配该正则的异常重试(推荐用于网络类不稳定错误)
注意:
-
--reruns必须为整数,设为0或负数会被忽略 -
--reruns-delay单位是秒,支持小数(如0.5) - 如果同时用了
--tb=short,重试过程中的中间失败堆栈默认不显示,只报最终结果
在 pytest.ini 中统一配置重试策略
把重试参数写进项目根目录的 pytest.ini,比每次敲命令更可靠:
[tool:pytest] addopts = --reruns 2 --reruns-delay 0.5 --only-rerun "requests.exceptions.Timeout|socket.timeout" testpaths = tests
这样只要运行 pytest 就自动生效。但要注意:
-
pytest.ini优先级高于命令行参数,除非显式用--reruns 5覆盖 -
--only-rerun的正则需匹配异常类的完整字符串(如socket.timeout不等于timeout) - 若项目混用不同稳定性要求的测试(如单元测试 vs API 测试),建议拆成不同
pytest配置段或用标记隔离
@pytest.mark.flaky 的细粒度控制
对个别特别不稳定的用例,可以用装饰器单独启用重试,绕过全局配置:
@pytest.mark.flaky(reruns=3, reruns_delay=1)
def test_api_fetch_user():
response = requests.get("https://api.example.com/user/123")
assert response.status_code == 200
关键点:
-
@pytest.mark.flaky的参数会覆盖全局--reruns和--reruns-delay - 它不支持
--only-rerun的异常白名单功能,所有异常都会触发重试 - 如果同时存在全局重试 +
@pytest.mark.flaky,后者优先生效;但不要混用两者来“叠加重试次数”,插件不会累加,只取最大值
真正容易被忽略的是:重试后的测试报告里,同一个用例可能出现多次结果(首次失败 + 后续重试成功),但 pytest 默认只显示最后一次状态。如果需要审计中间过程,得配合 --junitxml 或第三方报告工具解析原始 XML 输出。


















