pytest 的 marker 是声明式元数据标记机制,用于在收集阶段筛选测试;冒烟测试是快速验证核心路径的用例集,通过 @pytest.mark.smoke 标记并用 pytest -m smoke 执行,需预先注册 marker 且确保零外部依赖。

什么是 pytest 的 marker,它和冒烟测试有什么关系
pytest 的 @pytest.mark 不是装饰器语法糖,而是声明式元数据标记机制。冒烟测试(smoke test)本质是一组「快速验证核心路径是否跑通」的用例,不追求覆盖率,只关心关键链路是否崩。marker 本身不执行逻辑,但它让 pytest 能在收集阶段就过滤出带特定标签的测试函数——这正是实现冒烟筛选的底层支撑。
如何定义和使用 smoke marker
必须先注册 marker,否则运行时会警告(PytestUnknownMarkWarning),且 -m 过滤可能失效。注册方式有两种:
- 在
pytest.ini中显式声明:[tool:pytest] markers = smoke: marks a test as part of the smoke suite - 或用
pyproject.toml(推荐):[tool.pytest.ini_options] markers = ["smoke: marks a test as part of the smoke suite"]
标记测试函数时直接用 @pytest.mark.smoke,比如:
import pytest <p>def test_login_success(): assert True # 假设这是核心登录流程</p><p>@pytest.mark.smoke def test_api_health_check(): assert 2 + 2 == 4
运行命令:pytest -m smoke 就只执行带该标记的用例。注意:未标记的用例默认不会被包含,哪怕它们逻辑上也属于冒烟范围——标记必须显式添加。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
立即学习“Python免费学习笔记(深入)”;
为什么 -m "smoke" 有时不生效?常见陷阱
最常踩的坑是 marker 名字拼错、没注册、或误用了布尔表达式语法。例如:
-
pytest -m smoke✅ 正确:匹配所有含smoke标记的用例 -
pytest -m "smoke and not slow"❌ 若没定义slowmarker,整个表达式会静默失败,退化为运行全部用例(pytest 默认行为) -
@pytest.mark.smoke()❌ 多余括号会导致 marker 注册失败,实际等价于没标记 - 在类上加
@pytest.mark.smoke,但类内某个方法又用@pytest.mark.skip—— skip 优先级更高,该方法仍会被跳过,哪怕它被 smoke 标记了
验证 marker 是否生效,可用 pytest --collect-only -m smoke 查看仅收集到哪些用例,避免盲目运行。
冒烟测试不是越少越好,要守住「可部署前必过」底线
真正容易被忽略的不是语法,而是语义边界:一个 test_payment_submit 加了 @pytest.mark.smoke,但如果它依赖数据库迁移脚本、外部 mock 服务未启动、或需要预置测试账户,那它就不满足「冒烟」定义——冒烟测试必须能秒级完成、零外部强依赖、失败即阻断发布。建议把 setup/teardown 逻辑全收进 fixture,并用 scope="session" 预热必要资源,而不是靠 marker 掩盖不可靠性。

















