侧边栏壁纸
博主头像
一朵云的博客博主等级

拥抱生活,向阳而生。

  • 累计撰写 107 篇文章
  • 累计创建 28 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

pytest -- pytest-rerunfailures插件介绍和使用

一朵云
2024-01-11 / 0 评论 / 0 点赞 / 1359 阅读 / 4870 字

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_modifyitemspytest_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 测试执行逻辑
    """

0

评论区