pytest动态参数化测试
pytest dynamically parametrized test
我创建了一个 'dynamic' 参数列表,我将其传递给 parametrize。
OPTIONS = ['a', 'b', 'c']
def get_unique_pairs():
unique_list = []
for first in OPTIONS:
for second OPTIONS:
if first == second:
continue
unique_list.append({'first':first, 'second':second))
return unique_list
def some_func()
unique_pairs = get_unique_pairs()
result = []
for pair in unique_pair:
if test(pair):
continue
else:
result.append(pair)
return pair
@pytest.mark.parametrize('param', some_fnc())
def test_fnc(param):
first = param['first']
second = param['second']
我希望传递给 test_fnc
的输入是 [('a','b'),('a','c')...('c','b')]
,其中第一个和第二个元素永远不会相同。我正在使用一些额外的逻辑来进一步删除特定的对。
当我 运行 测试时,我得到输出:
::test_fnc[param0] PASSED
::test_fnc[param1] PASSED
::test_fnc[param2] PASSED
我有两个问题:
- 我不完全确定如何描述我正在做什么以查找更多文档/帮助。
- 我想要更多的描述性输出(即不是
param0
),我想继续使用字典将数据传递给测试。
- 正如评论中Paulo Scardine所说,不要重新发明轮子,使用
itertools.combinations
。
- 您正在寻找
ids
argument in parametrize
hook。它要么是每个参数的名称列表,要么是接受参数和 returns 字符串的函数 - repr
是内置类型的简单解决方案。
组合示例:
import itertools
import pytest
opts = ['a', 'b', 'c']
@pytest.mark.parametrize('param', itertools.combinations(opts, 2), ids=repr)
def test_fn(param):
first = param[0]
second = param[1]
assert first != second
我会这样写:
import pytest
import itertools
OPTIONS = ['a', 'b', 'c']
@pytest.mark.parametrize(
'param',
itertools.permutations(OPTIONS, 2),
ids=lambda pair: "first={}, second={}".format(*pair)
)
def test_fn(param):
first, second = param
assert first != second
结果:
> pytest --verbose
================================ test session starts =================================
platform linux2 -- Python 2.7.12, pytest-3.6.1, py-1.5.3, pluggy-0.6.0 -- /usr/bin/python
cachedir: .pytest_cache
rootdir: /home/paulos/work/lixo/tests, inifile:
collected 6 items
test_foo.py::test_fn[first=a, second=b] PASSED [ 16%]
test_foo.py::test_fn[first=a, second=c] PASSED [ 33%]
test_foo.py::test_fn[first=b, second=a] PASSED [ 50%]
test_foo.py::test_fn[first=b, second=c] PASSED [ 66%]
test_foo.py::test_fn[first=c, second=a] PASSED [ 83%]
test_foo.py::test_fn[first=c, second=b] PASSED [100%]
================================ 6 passed in 0.03 seconds ================================
[更新]
I think this answer is the solution I will use. Every day is a school day! (Out of curiosity is there a way I could be the 'param' into something like 'first, second' so to have test_foo(param) be test_foo(first, second). I'm not sure that actually helps anything... but I am curious – F. Elliot
如果您不介意使用 test_fn[a-b]
而不是 test_fn[a, b]
:
@pytest.mark.parametrize(
'first,second',
itertools.permutations(OPTIONS, 2),
)
def test_fn(first, second):
assert first != second
在实践中,我们并没有真正地 运行 测试 --verbose
,所以大多数时候每个测试的输出只是一个点。
我创建了一个 'dynamic' 参数列表,我将其传递给 parametrize。
OPTIONS = ['a', 'b', 'c']
def get_unique_pairs():
unique_list = []
for first in OPTIONS:
for second OPTIONS:
if first == second:
continue
unique_list.append({'first':first, 'second':second))
return unique_list
def some_func()
unique_pairs = get_unique_pairs()
result = []
for pair in unique_pair:
if test(pair):
continue
else:
result.append(pair)
return pair
@pytest.mark.parametrize('param', some_fnc())
def test_fnc(param):
first = param['first']
second = param['second']
我希望传递给 test_fnc
的输入是 [('a','b'),('a','c')...('c','b')]
,其中第一个和第二个元素永远不会相同。我正在使用一些额外的逻辑来进一步删除特定的对。
当我 运行 测试时,我得到输出:
::test_fnc[param0] PASSED
::test_fnc[param1] PASSED
::test_fnc[param2] PASSED
我有两个问题:
- 我不完全确定如何描述我正在做什么以查找更多文档/帮助。
- 我想要更多的描述性输出(即不是
param0
),我想继续使用字典将数据传递给测试。
- 正如评论中Paulo Scardine所说,不要重新发明轮子,使用
itertools.combinations
。 - 您正在寻找
ids
argument inparametrize
hook。它要么是每个参数的名称列表,要么是接受参数和 returns 字符串的函数 -repr
是内置类型的简单解决方案。
组合示例:
import itertools
import pytest
opts = ['a', 'b', 'c']
@pytest.mark.parametrize('param', itertools.combinations(opts, 2), ids=repr)
def test_fn(param):
first = param[0]
second = param[1]
assert first != second
我会这样写:
import pytest
import itertools
OPTIONS = ['a', 'b', 'c']
@pytest.mark.parametrize(
'param',
itertools.permutations(OPTIONS, 2),
ids=lambda pair: "first={}, second={}".format(*pair)
)
def test_fn(param):
first, second = param
assert first != second
结果:
> pytest --verbose
================================ test session starts =================================
platform linux2 -- Python 2.7.12, pytest-3.6.1, py-1.5.3, pluggy-0.6.0 -- /usr/bin/python
cachedir: .pytest_cache
rootdir: /home/paulos/work/lixo/tests, inifile:
collected 6 items
test_foo.py::test_fn[first=a, second=b] PASSED [ 16%]
test_foo.py::test_fn[first=a, second=c] PASSED [ 33%]
test_foo.py::test_fn[first=b, second=a] PASSED [ 50%]
test_foo.py::test_fn[first=b, second=c] PASSED [ 66%]
test_foo.py::test_fn[first=c, second=a] PASSED [ 83%]
test_foo.py::test_fn[first=c, second=b] PASSED [100%]
================================ 6 passed in 0.03 seconds ================================
[更新]
I think this answer is the solution I will use. Every day is a school day! (Out of curiosity is there a way I could be the 'param' into something like 'first, second' so to have test_foo(param) be test_foo(first, second). I'm not sure that actually helps anything... but I am curious – F. Elliot
如果您不介意使用 test_fn[a-b]
而不是 test_fn[a, b]
:
@pytest.mark.parametrize(
'first,second',
itertools.permutations(OPTIONS, 2),
)
def test_fn(first, second):
assert first != second
在实践中,我们并没有真正地 运行 测试 --verbose
,所以大多数时候每个测试的输出只是一个点。