You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pytest测试文件中对指定标记取反,排除目标控制器?

实现pytest标记取反(排除指定控制器)

要实现类似@pytest.notmark.pcm62的标记取反功能,无需手动添加所有其他控制器标记,同时不影响原有测试的执行逻辑,可以通过自定义装饰器+pytest钩子函数来实现:

步骤1:在conftest.py中添加配置

在测试目录下的conftest.py文件中写入以下代码:

import pytest

class NotMark:
    def __getattr__(self, controller):
        # 当访问pytest.notmark.xxx时,返回all_except标记,参数为xxx
        return pytest.mark.all_except(controller)

# 把NotMark实例绑定到pytest.notmark上
pytest.notmark = NotMark()

def pytest_configure(config):
    # 注册自定义标记,避免pytest抛出未注册标记的警告
    config.addinivalue_line(
        "markers",
        "all_except(controller): 仅在指定控制器之外的环境运行测试"
    )

def pytest_collection_modifyitems(config, items):
    # 获取命令行传入的标记表达式
    target_mark = config.getoption("-m") or ""
    
    for test_item in items:
        # 检查当前测试是否有all_except标记
        exclude_mark = test_item.get_closest_marker("all_except")
        if exclude_mark:
            excluded_controller = exclude_mark.args[0]
            # 如果命令行指定的标记正好是要排除的控制器,跳过该测试
            if target_mark == excluded_controller:
                test_item.add_marker(
                    pytest.mark.skip(reason=f"该测试排除在控制器 {excluded_controller} 上运行")
                )

步骤2:编写带排除标记的测试

在测试脚本中,直接用@pytest.notmark.pcm62装饰需要排除的测试:

import pytest

# 原有测试:在所有控制器上都能被触发
@pytest.mark.pcm33
@pytest.mark.pcm21
@pytest.mark.pcm62
@pytest.mark.pcm52
@pytest.mark.pcm61
def test_something():
    assert True

# 新测试:排除pcm62控制器,其他控制器均可触发
@pytest.notmark.pcm62
def test_something_excluding_pcm62():
    assert True

效果验证

  • 运行pytest -m pcm62:test_something会执行,test_something_excluding_pcm62被跳过
  • 运行pytest -m pcm33:两个测试都会执行
  • 运行pytest(不带标记):两个测试都会执行

这个方案完全符合需求:无需手动罗列所有允许的控制器标记,仅需指定要排除的目标;且原有测试的执行逻辑不受任何影响。

内容的提问来源于stack exchange,提问作者Kjeld Flarup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:56:09