Pytest 插件开发入门:手把手写一个测试用例重试插件

本文将逐步指导你开发一个实用的Pytest插件——测试用例重试插件。当测试用例意外失败时(如网络波动导致),该插件能自动重试执行,提升测试稳定性。


1. 插件功能设计
  • 核心逻辑:检测测试失败 → 自动重试 $n$ 次($n$ 可配置)
  • 终止条件
    • 重试成功:标记为通过
    • 达到最大重试次数:标记为失败
  • 日志记录:输出每次重试结果

2. 开发环境准备

确保安装以下依赖:

pip install pytest>=6.0


3. 创建插件文件

新建文件 pytest_retry.py,包含以下基础结构:

import pytest

def pytest_addoption(parser):
    parser.addoption("--retries", action="store", default=3, 
                     help="失败用例重试次数 (默认: 3)")


4. 实现重试逻辑

通过Pytest的钩子函数 pytest_runtest_makereport 捕获测试结果:

class RetryPlugin:
    def __init__(self, max_retries):
        self.max_retries = max_retries
    
    def pytest_runtest_makereport(self, item, call):
        # 仅处理失败用例
        if call.excinfo is None:
            return
        
        # 获取当前重试次数
        retries = getattr(item, "retries", 0)
        if retries < self.max_retries:
            item.retries = retries + 1
            pytest.exit(f"重试中 ({retries+1}/{self.max_retries})", returncode=3)

def pytest_configure(config):
    config.pluginmanager.register(
        RetryPlugin(max_retries=config.getoption("--retries"))
    )


5. 注册钩子函数

conftest.py 中激活插件:

pytest_plugins = ["pytest_retry"]


6. 测试插件效果

创建测试用例 test_demo.py

import random

def test_flaky_example():
    assert random.random() > 0.3  # 70%概率通过

执行命令(设置重试3次):

pytest --retries=3

输出示例

重试中 (1/3)
重试中 (2/3)
PASSED  # 第三次成功


7. 数学原理说明

设单次测试通过概率为 $p$,则 $n$ 次重试后通过的概率为: $$P_{\text{pass}} = 1 - (1-p)^n$$ 例如 $p=0.7$ 时,$n=3$ 次重试后通过率提升至: $$1 - (0.3)^3 = 0.973$$


进阶优化方向
  1. 指数退避:重试间隔按 $t \cdot 2^{k}$ 增长($k$ 为重试次数)
  2. 错误过滤:仅重试特定异常(如 ConnectionError
  3. 重试报告:生成详细的HTML重试日志

通过这个简单插件,你已掌握Pytest插件开发的核心流程!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐