参数化和 运行 pytest 中的单个测试
parametrize and running a single test in pytest
如何 运行 从配置了参数化的集合中进行单个测试?
假设我有以下测试方法:
@pytest.mark.parametrize(PARAMETERS_LIST, PARAMETERS_VALUES)
def test_my_feature(self, param1, param2, param3):
"""
test doc
"""
if param1 == 'value':
assert True
else:
print 'not value'
assert False
我有 3 个参数,我为它们生成了一个包含 15 个不同可能值的列表,以测试函数。
我怎么能运行只是其中之一呢?除了明显的方式 - 给出一个值而不是 15.
您可以 specify the tests to run 通过使用 -k
标志过滤匹配字符串表达式的测试。使用 parametrize 时,pytest 使用以下约定命名每个测试用例:
test_name['-' separated test inputs]
例如
test_name[First_test_value-Second_test_value-N_test_value]
为运行选择一个特定的测试是将以上所有内容放在一起的问题
pytest -k 'my_test[value_1-value_2]'
或
pytest -k my_test\[value_1-value_2\]
你需要转义方括号。
我能想到两种可能的解决方案。
- 使用你想要的测试名称运行,并执行它
- 使用
-k
参数 运行 测试匹配给定子字符串表达式
解决方案 1
使用以下命令查看未 运行 测试的名称:
pytest --collect-only -q # use --co if pytest 5.3.0+ instead of --collect-only
使用你想要的测试名称运行,假设测试名为test_file_name.py::test_name[value1-value2-value3]
,那么使用下面的命令运行它:
pytest test_file_name.py::test_name[value1-value2-value3]
注意:如果标识符中有空格,请务必使用引号。
解决方案 2
该解决方案由 Enrique Saez 提供,主要包括传递部分测试名称:
pytest -k -value3]
我知道这个问题已经得到解答,但我对我的用例的答案不满意。
我有一些参数化测试,如果我经常 运行 的话,它们花费的时间比我希望的要长。能够在命令行上将参数传递给 pytest 以设置每个参数化测试的最大数量 运行s 将很有用。这样我就可以确信我的代码适用于某些数据集,而不必等待检查每个数据集,但仍然保留用于测试每个数据集的代码(运行 不那么频繁)。
我通过将以下内容添加到我的 conftest.py
中实现了这一点
def pytest_addoption(parser):
parser.addoption(
"--limit",
action="store",
default=-1,
type=int,
help="Maximum number of permutations of parametrised tests to run",
)
def pytest_collection_modifyitems(session, config, items):
def get_base_name(test_name):
"""
Get name of test without parameters
Parametrised tests have the [ character after the base test name, followed by
the parameter values. This removes the [ and all that follows from test names.
"""
try:
return test_name[: test_name.index("[")]
except ValueError:
return test_name
limit = config.getoption("--limit")
if limit >= 0:
tests_by_name = {item.name: item for item in items}
test_base_names = set(get_base_name(name) for name in tests_by_name.keys())
tests_to_run = []
for base_name in test_base_names:
to_skip = [t for n, t in tests_by_name.items() if base_name in n][limit:]
for t in to_skip:
t.add_marker("skip")
如何 运行 从配置了参数化的集合中进行单个测试? 假设我有以下测试方法:
@pytest.mark.parametrize(PARAMETERS_LIST, PARAMETERS_VALUES)
def test_my_feature(self, param1, param2, param3):
"""
test doc
"""
if param1 == 'value':
assert True
else:
print 'not value'
assert False
我有 3 个参数,我为它们生成了一个包含 15 个不同可能值的列表,以测试函数。
我怎么能运行只是其中之一呢?除了明显的方式 - 给出一个值而不是 15.
您可以 specify the tests to run 通过使用 -k
标志过滤匹配字符串表达式的测试。使用 parametrize 时,pytest 使用以下约定命名每个测试用例:
test_name['-' separated test inputs]
例如
test_name[First_test_value-Second_test_value-N_test_value]
为运行选择一个特定的测试是将以上所有内容放在一起的问题
pytest -k 'my_test[value_1-value_2]'
或
pytest -k my_test\[value_1-value_2\]
你需要转义方括号。
我能想到两种可能的解决方案。
- 使用你想要的测试名称运行,并执行它
- 使用
-k
参数 运行 测试匹配给定子字符串表达式
解决方案 1
使用以下命令查看未 运行 测试的名称:
pytest --collect-only -q # use --co if pytest 5.3.0+ instead of --collect-only
使用你想要的测试名称运行,假设测试名为test_file_name.py::test_name[value1-value2-value3]
,那么使用下面的命令运行它:
pytest test_file_name.py::test_name[value1-value2-value3]
注意:如果标识符中有空格,请务必使用引号。
解决方案 2
该解决方案由 Enrique Saez 提供,主要包括传递部分测试名称:
pytest -k -value3]
我知道这个问题已经得到解答,但我对我的用例的答案不满意。
我有一些参数化测试,如果我经常 运行 的话,它们花费的时间比我希望的要长。能够在命令行上将参数传递给 pytest 以设置每个参数化测试的最大数量 运行s 将很有用。这样我就可以确信我的代码适用于某些数据集,而不必等待检查每个数据集,但仍然保留用于测试每个数据集的代码(运行 不那么频繁)。
我通过将以下内容添加到我的 conftest.py
def pytest_addoption(parser):
parser.addoption(
"--limit",
action="store",
default=-1,
type=int,
help="Maximum number of permutations of parametrised tests to run",
)
def pytest_collection_modifyitems(session, config, items):
def get_base_name(test_name):
"""
Get name of test without parameters
Parametrised tests have the [ character after the base test name, followed by
the parameter values. This removes the [ and all that follows from test names.
"""
try:
return test_name[: test_name.index("[")]
except ValueError:
return test_name
limit = config.getoption("--limit")
if limit >= 0:
tests_by_name = {item.name: item for item in items}
test_base_names = set(get_base_name(name) for name in tests_by_name.keys())
tests_to_run = []
for base_name in test_base_names:
to_skip = [t for n, t in tests_by_name.items() if base_name in n][limit:]
for t in to_skip:
t.add_marker("skip")