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

Pytest中-k与-m参数的区别:为何测试输出一致?

Pytest中-k与-m参数的区别

问题背景

我创建并使用了自定义标记orange、apple和pineapple,配置及测试代码如下:

配置文件(pytest.ini)

# "pytest.ini"

[pytest]
markers =
    orange: Orange marker
    apple: Apple marker
    pineapple: Pineapple marker

测试代码

import pytest

@pytest.mark.orange
def test1():
    assert True

@pytest.mark.apple
def test2():
    assert True

@pytest.mark.pineapple
def test3():
    assert True

随后分别执行pytest -k orange和pytest -m orange命令,得到了完全相同的测试输出:

=================== test session starts ===================
platform win32 -- Python 3.9.13, pytest-7.4.0, pluggy-1.2.0
django: settings: core.settings (from ini)
rootdir: C:\Users\kai\test-django-project2
configfile: pytest.ini
plugins: django-4.5.2
collected 3 items / 2 deselected / 1 selected

tests\test_store.py .                                [100%]

============= 1 passed, 2 deselected in 0.09s =============

请问Pytest中-k与-m参数的区别是什么?


核心区别

1. 作用对象完全不同

  • *-k*是基于测试项的名称做字符串匹配,匹配范围包括测试函数名、测试类名、模块文件名等。不管测试有没有加标记,只要名称里包含指定字符串,就会被选中。比如你要是有个测试函数叫test_orange_juice,哪怕没加@pytest.mark.orange,用pytest -k orange也会命中它。
  • *-m*是专门匹配预定义的测试标记,只有被显式标记了对应标签的测试项才会被选中,和测试名称完全无关。比如给test_drink加@pytest.mark.orange,用pytest -m orange会选中它,但pytest -k orange不会。

2. 匹配逻辑的侧重不同

  • *-k*支持灵活的字符串逻辑组合,比如pytest -k "orange or apple"(选中名称含orange或apple的测试)、pytest -k "not pineapple"(排除名称含pineapple的测试),还能结合类名和函数名筛选,比如pytest -k "TestCheckout and orange"。
  • *-m*是基于标记的逻辑组合,同样支持or/and/not,比如pytest -m "orange or apple"(选中带orange或apple标记的测试),但它只识别你在配置文件里声明过的标记,不会碰名称相关的内容。

3. 语义与使用场景不同

  • *-k*属于临时快速筛选,适合开发时根据名称快速定位测试,没有严格的规范要求,想到什么字符串就搜什么。
  • *-m*是结构化的分类筛选,需要先在pytest.ini里声明标记,语义更清晰,适合按测试类别(比如功能模块、测试类型:单元/集成/UI)来组织测试套件,团队协作时规范性更强。

你这次测试中两者输出一致只是巧合:你的标记名没有和其他测试的名称重叠,且带orange标记的测试刚好没有其他同名或含该字符串的测试项,换个场景结果就会不一样。

内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:53:11