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
相关产品推荐
相关产品推荐

