如何在pytest中运行含空格、引号的参数化单例测试?
pytest命令行指定参数化测试用例的问题与解决方法
问题场景
单参数测试的命令行执行问题
有如下单参数测试代码:
@pytest.mark.parametrize('param', ['my param', 'my param 2']) def test_param(self, param): ...
用python3 -m pytest -s -k "test_param"运行一切正常,但尝试用python3 -m pytest -s -k "test_param[my param]"单独运行特定参数的用例时,会报错:
ERROR: Wrong expression passed to '-k': my param: at column 4: expected end of input; got identifier
含特殊字符的参数问题
如果参数字符串包含单引号',会触发类似报错:
ERROR: Wrong expression passed to '-k': ... : at column 51: expected end of input; got left parenthesis
要是参数字符串同时包含双引号"和单引号',用-k选项时会因为字符串提前终止,直接无法执行。
多参数测试的执行困惑
对于下面这种多参数的测试函数,不知道怎么单独指定参数运行:
@pytest.mark.parametrize('input, expected', [ ( """ integer :: & my_var !< my comment """, {'my_var': 'my comment'} ) ]) def test_fetch_variable_definitions_multiline(input,expected): ...
目前只能靠字典索引(用range(len(my_dict))作为参数)绕开,但想直接在命令行指定参数。
解决方法
单参数用例的精准指定
-k选项的表达式要符合pytest的匹配语法,带空格的参数得用引号包裹,还要注意shell的转义:
- 用双引号包裹整个
-k参数,内部字符串用单引号:python3 -m pytest -s -k "test_param and param='my param'" - 用单引号包裹整个
-k参数,内部用双引号(适合参数含单引号的情况):
这里用python3 -m pytest -s -k 'test_param and param="my param with '\''single quote'\''"''\''转义单引号,避免shell解析出错。
多参数用例的指定
对于多参数测试,可以通过匹配参数变量的具体值筛选:
- 比如匹配
input中包含my_var的用例:python3 -m pytest -s -k "test_fetch_variable_definitions_multiline and 'my_var' in input" - 或者匹配
expected字典里的键值对:python3 -m pytest -s -k "test_fetch_variable_definitions_multiline and expected.get('my_var') == 'my comment'"
更可靠的替代方案:-m标记或自定义ID
如果-k匹配太麻烦,还有两种更稳妥的办法:
- 给特定用例加标记:
然后用@pytest.mark.parametrize('param', [ pytest.param('my param', marks=pytest.mark.my_case), pytest.param('my param 2', marks=pytest.mark.another_case) ]) def test_param(self, param): ...-m运行指定标记的用例:python3 -m pytest -s -m my_case - 自定义参数化ID:
给每个参数化用例设置唯一ID,比如单参数场景:
然后用@pytest.mark.parametrize('param', [ ('my param',), ('my param 2',) ], ids=['case_with_space', 'second_case'])::指定ID运行:
多参数场景也一样,自定义ID后直接指定:python3 -m pytest -s test_file.py::TestClass::test_param::case_with_space
运行命令:@pytest.mark.parametrize('input, expected', [ ( """ integer :: & my_var !< my comment """, {'my_var': 'my comment'} ) ], ids=['multiline_var_test'] ) def test_fetch_variable_definitions_multiline(input,expected): ...python3 -m pytest -s test_file.py::test_fetch_variable_definitions_multiline::multiline_var_test
内容的提问来源于stack exchange,提问作者Yes
相关产品推荐
相关产品推荐

