加了 @pytest.mark.slow 却不生效是因为 pytest 默认开启标记严格校验,未注册的标记名会被忽略或警告;需在 pytest.ini 或 pyproject.toml 中注册 markers,或避免大小写错误、正确使用布尔表达式及作用域规则。

直接回答:用 @pytest.mark.标签名 给测试函数打标记,再通过 pytest -m 标签名 运行——但标记名必须提前注册或禁用严格模式,否则会报 PytestUnknownMarkWarning 或直接跳过。
为什么加了 @pytest.mark.slow 却不生效?
常见现象是运行 pytest -m slow 后提示 1 deselected 或警告 PytestUnknownMarkWarning。这是因为 pytest 默认开启标记严格校验(markers 配置未声明),遇到未注册的标记名就忽略该测试。
- 解决方式一:在
pytest.ini或pyproject.toml中显式注册标记,例如在pytest.ini加入:
[tool:pytest]
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
integration: marks tests requiring external services
--strict-markers 的反向开关——不推荐,容易掩盖配置问题@pytest.mark.SLOW 和 -m slow 不匹配如何组合多个标记筛选?
支持布尔逻辑表达式,但语法有约束:空格是 AND,or 和 not 必须小写且前后带空格,括号需转义或用引号包裹。
- 运行所有带
slow且不带integration的测试:pytest -m "slow and not integration" - 运行任一标记匹配的测试:
pytest -m "slow or integration" - 避免 shell 解析错误:当表达式含括号时,务必用单引号包裹整个表达式,如
pytest -m 'slow and (not unit)' - 标记本身可以带参数,例如
@pytest.mark.parametrize('x', [1,2])是另一机制,和@pytest.mark.xxx无关
标记写在类上 vs 写在函数上,行为有何不同?
标记作用域按就近原则继承:函数上的标记优先级高于类,类上的标记会被所有未覆盖的方法继承。
立即学习“Python免费学习笔记(深入)”;
- 给类加标记:
@pytest.mark.integration→ 类内所有测试函数默认带此标记 - 给某个函数加
@pytest.mark.unit→ 该函数同时拥有unit和integration两个标记(除非显式取消) - 想排除某方法的类级标记?只能显式覆盖:
@pytest.mark.integration(False)不合法;正确做法是不依赖继承,逐个标注 - 标记不支持继承链穿透,父类的
@pytest.mark.xxx不会自动传给子类
标记不是装饰器链的一部分,它只影响 pytest 的收集逻辑,不改变函数运行时行为;真正容易被忽略的是:标记注册必须出现在 pytest 启动前读取的配置文件里,放在 conftest.py 中的 pytest_configure 钩子注册也有效,但不如配置文件稳定。


















