pytest -- pytest-rerunfailures插件介绍和使用
简介:
pytest-rerunfailures
允许在用例测试失败后自动重新运行测试,是个通用失败重试插件。
这对于处理那些由于临时性问题(如网络波动、服务短暂不可用等)导致的偶发性失败特别有用,可以显著提高自动化测试的稳定性和可靠性。
准备:
安装插件
pip install pytest-rerunfailures
使用方法:
方法一:命令行全局配置
pytest --reruns 3 # 所有测试失败后重试3次
pytest --reruns 3 --reruns-delay 2 # 每次重试间隔2秒
方法二:标记单个测试用例
@pytest.mark.flaky(reruns=3, reruns_delay=1)
def test_unstable_api():
# 这个测试失败会重试3次,每次间隔1秒
...
方法三:配置pytest.ini
[pytest]
# addopts: 指定运行 pytest 时默认附加的命令行选项
addopts =
# 重试次数
--reruns 5
# 重试间隔时间
--reruns-delay 1
方法四:使用钩子函数
def pytest_collection_modifyitems(config, items):
"""
在测试收集阶段,为每个测试项动态添加 flaky 重试
这是推荐时机,确保标记被插件正确识别
"""
for item in items:
# 可选:跳过某些测试
if item.get_closest_marker("skip") is not None:
continue
if item.get_closest_marker("xfail") is not None:
continue
# 添加 flaky 重试
item.add_marker(
# pytest.mark.flaky(reruns=2, reruns_delay=1)
pytest.mark.flaky(reruns=3, reruns_delay=1)
)
自定义重试策略
仅针对 GET
请求方式进行重试,至于其他请求方式都无需重试!
思路:
基于方法四,pytest_collection_modifyitems
或 pytest_runtest_setup
钩子函数,并通过函数名反推出 yaml
文件的名称,读取其中的 method
值,判断是否为GET,是的话添加 pytest.mark.flaky
重试标记。(这里需要约定函数名和 yaml
文件名,如:函数名为:test_login();yaml
文件名为:login.yml)
conftest.py
# --------------------------
# 自定义重试机制
# --------------------------
def pytest_collection_modifyitems(config, items):
"""
在测试收集阶段,为每个测试项动态添加 flaky 重试
这是推荐时机,确保标记被插件正确识别.
这里进行判断,只有get请求进行重试,其他请求方式不处理。
"""
for item in items:
# 获取测试函数名,如 test_sdk_login
func_name = item.originalname or item.name.split("[")[0]
if not func_name.startswith("test_"):
continue
# 推导 YAML 文件名
yaml_filename = f"{func_name[5:]}.yml"
yaml_path = os.path.join("data", yaml_filename)
if not os.path.exists(yaml_path):
continue
# 读取 YAML
loader = ConfigLoader(yaml_path)
method = loader.get("method") # ✅ 获取 method
if method == "GET":
# 使用 pytest-rerunfailures 插件的重试功能
item.add_marker(pytest.mark.flaky(reruns=3, reruns_delay=1))
login.yml
里面包含了 method
。
epic: "SDK3"
feature: "sdk后台"
story: "获取包名"
url: /getPackageName
method: GET
test_cases:
- id: "getPackageName_smoke"
description: "冒烟测试——获取包名信息"
severity: 5
request_data:
id: 1
expected_response:
code: 200
message: 成功
data: "com.test.a"
import allure
from utils.http_client import HttpClient
# -------------------- 获取包名接口 --------------------
def test_login(test_data, allure_report_supplement):
_run_api_test(test_data, allure_report_supplement)
# -------------------- 通用执行函数 --------------------
def _run_api_test(test_data, allure_report_supplement):
"""
通用 API 测试执行逻辑
"""
评论区