如何让pytest仅运行带nightly标记的特定参数化测试用例?
如何让pytest仅执行参数组合均带指定标记的测试用例?
问题描述
我有如下测试代码:
import pytest @pytest.mark.parametrize("project_name", [ pytest.param("default", marks=pytest.mark.defa), pytest.param("remote", marks=[pytest.mark.remote, pytest.mark.nightly]) ]) @pytest.mark.parametrize("spec_file", [ pytest.param("some_A.json", marks=pytest.mark.nightly), pytest.param("some_B.json") ]) def test_A(self, project_name, spec_file): assert 1==1
当执行命令 pytest -m nightly --collect-only -qq <path_to_test_file> 收集带nightly标记的测试时,得到的输出是:
<Function 'test_A[some_A.json-remote]'> <Function 'test_A[some_A.json-default]'> <Function 'test_A[some_B.json-remote]'>
但我预期仅收集/执行 <Function 'test_A[some_A.json-remote]'> 这一个测试用例,请问该如何实现?
问题原因
pytest默认的标记筛选是逻辑或的关系:只要测试用例的任意一个参数带有nightly标记,就会被选中。当前输出的三个用例分别满足:
some_A.json-default:spec_file参数带nightly标记some_B.json-remote:project_name参数带nightly标记some_A.json-remote:两个参数都带nightly标记
要仅选中两个参数都带nightly的用例,需要实现逻辑与的筛选逻辑,以下是几种可行方法:
方法1:直接通过参数值精准筛选(最简单)
使用-k参数匹配参数组合的名称,直接定位目标用例:
pytest -k "remote and some_A.json" --collect-only -qq <path_to_test_file>
这种方式无需修改代码,适合临时执行特定组合的场景。
方法2:通过钩子函数过滤标记组合
在测试目录下的conftest.py中添加以下代码,自定义筛选逻辑:
def pytest_collection_modifyitems(config, items): # 仅当使用-m nightly参数时生效 if config.getoption("-m") == "nightly": filtered_items = [] for item in items: # 统计测试用例上的nightly标记数量 nightly_marks = list(item.iter_markers(name="nightly")) # 两个参数都带nightly标记时,会有2个nightly标记(分别来自两个param) if len(nightly_marks) == 2: filtered_items.append(item) # 替换为筛选后的用例列表 items[:] = filtered_items
之后执行原命令 pytest -m nightly --collect-only -qq <path_to_test_file>,就只会选中目标用例。
方法3:给目标组合单独打专属标记
如果需要长期保留这个特定组合的执行入口,可以直接给该参数组合单独打标记:
import pytest # 定义通用参数 project_params = [ pytest.param("default", marks=pytest.mark.defa), pytest.param("remote", marks=[pytest.mark.remote, pytest.mark.nightly]) ] spec_params = [ pytest.param("some_A.json", marks=pytest.mark.nightly), pytest.param("some_B.json") ] # 给目标组合单独定义测试用例并打标记 @pytest.mark.parametrize("project_name, spec_file", [ ("remote", "some_A.json"), ], marks=pytest.mark.nightly_exact) def test_A_exact(self, project_name, spec_file): assert 1 == 1 # 保留原有的参数化测试用例 @pytest.mark.parametrize("project_name", project_params) @pytest.mark.parametrize("spec_file", spec_params) def test_A(self, project_name, spec_file): assert 1 == 1
执行时使用专属标记筛选:
pytest -m nightly_exact --collect-only -qq <path_to_test_file>
内容的提问来源于stack exchange,提问作者Joshi
相关产品推荐
相关产品推荐

