常用的 pytest.mark 标记整理

常用的 pytest.mark 标记整理

基本概念

  1. 本质:一种装饰器(decorator),用于给测试项添加额外的信息
  2. 作用:在不修改测试逻辑的情况下,改变测试的执行方式
  3. 位置:可以标记测试函数、测试类或测试模块

基础标记

  1. @pytest.mark.skip - 无条件跳过测试

    @pytest.mark.skip(reason="功能尚未实现")
    def test_function():
        ...
    
  2. @pytest.mark.skipif - 条件性跳过测试

    @pytest.mark.skipif(sys.version_info < (3, 8), reason="需要 Python 3.8 或更高版本")
    def test_function():
        ...
    
  3. @pytest.mark.xfail - 预期测试会失败

    @pytest.mark.xfail(reason="已知问题,待修复")
    def test_function():
        ...
    
  4. @pytest.mark.parametrize - 参数化测试

    @pytest.mark.parametrize("input,expected", [(1, 2), (2, 3)])
    def test_increment(input, expected):
        assert input + 1 == expected
    

测试组织标记

  1. @pytest.mark.smoke - 标记冒烟测试

    @pytest.mark.smoke
    def test_login():
        ...
    
  2. @pytest.mark.regression - 标记回归测试

    @pytest.mark.regression
    def test_checkout():
        ...
    
  3. @pytest.mark.ui / @pytest.mark.api - 按测试类型标记

    @pytest.mark.ui
    def test_homepage_load():
        ...
    

特殊功能标记

  1. @pytest.mark.timeout - 设置测试超时时间

    @pytest.mark.timeout(10)  # 10秒超时
    def test_long_running():
        ...
    
  2. @pytest.mark.filterwarnings - 过滤警告

    @pytest.mark.filterwarnings("ignore:deprecated")
    def test_with_deprecation():
        ...
    
  3. @pytest.mark.usefixtures - 使用fixture

    @pytest.mark.usefixtures("setup_db")
    class TestDatabase:
        ...
    

自定义标记

你可以创建自己的标记,首先需要在 pytest.ini 中注册:

[pytest]
markers =
    slow: 标记为慢速测试
    integration: 集成测试
    nightly: 夜间执行的测试

然后使用:

@pytest.mark.slow
def test_complex_calculation():
    ...

执行次数相关

  1. @pytest.mark.flaky - 自动重试失败的测试

    @pytest.mark.flaky(reruns=3)  # 失败后自动重试3次
    def test_flaky_network():
        ...
    
  2. @pytest.mark.repeat - 重复执行测试多次

    @pytest.mark.repeat(5)  # 重复执行5次
    def test_random_result():
        ...
    

执行控制标记

  1. @pytest.mark.flaky (扩展)

    • reruns: 重试次数
    • reruns_delay: 重试间隔(秒)
    @pytest.mark.flaky(reruns=3, reruns_delay=2)  # 失败后重试3次,每次间隔2秒
    
  2. @pytest.mark.repeat (扩展)

    @pytest.mark.repeat(10)  # 执行10次
    @pytest.mark.parametrize("input", [1, 2])  # 可以和参数化组合使用
    def test_combo(input):
        # 总共会执行 10×2=20 次
        ...
    

执行控制组合使用

命令行控制执行次数

  1. 重复执行所有测试

    pytest --count=5  # 所有测试执行5次
    
  2. 仅重复执行失败测试

    pytest --reruns 3  # 相当于给所有测试添加 @pytest.mark.flaky(reruns=3)
    
  3. 组合使用示例

    pytest --count=2 --reruns=3 -x  # 执行2轮,每轮中失败测试重试3次,遇到第一个失败就停止
    

代码中精细控制

@pytest.mark.flaky(reruns=3, reruns_delay=1)
@pytest.mark.repeat(5)
@pytest.mark.timeout(30)
def test_important_feature():
    # 会执行5次,每次失败后重试3次,每次间隔1秒,超时30秒
    ...

最佳实践建议

  1. 稳定性测试:对偶发失败测试使用 @pytest.mark.flaky
  2. 性能基准:使用 @pytest.mark.repeat 进行多次执行取平均值
  3. 资源控制:结合 @pytest.mark.timeout 防止无限执行
  4. 重要测试:对核心功能组合使用多种执行控制
  5. 避免滥用:只在必要时使用执行控制,过多重试可能掩盖问题

查看执行统计

使用 -v 查看详细执行情况:

pytest -v --reruns 3 --count 2

会显示每次重试和重复执行的信息,方便分析偶发问题。

这种组合使用方式特别适合:

  • 网络请求测试
  • 多线程/并发测试
  • 依赖外部服务的测试
  • 性能基准测试

使用建议

  1. 使用 pytest -m 按标记运行测试:

    pytest -m smoke  # 只运行冒烟测试
    pytest -m "not slow"  # 不运行慢速测试
    
  2. 查看所有可用标记:

    pytest --markers
    
  3. 合理组织标记,避免过度使用,保持测试套件的可维护性。

你可能感兴趣的:(pytest,python,开发语言)