在一个测试类中有多个测试。我想使用字典来参数化类。
字典结构:{key1: [val_1, val2], key2: [val_3, val4]}
测试:
@pytest.mark.parametrize('key, value', [(k, v) for k, l in some_dict.items() for v in l], scope='class')
# ^^^ the best solution that I've found but still not as expected, and without IDS ^^^
class TestSomething:
def test_foo(self):
assert True
def test_boo(self):
assert True
期望顺序(ids
包括键和值都是对象,并且可以提供'.name'属性):
<Class TestSomething>
<Function test_foo[key1_name-val1_name]>
<Function test_boo[key1_name-val1_name]>
<Function test_foo[key1_name-val2_name]>
<Function test_boo[key1_name-val2_name]>
<Function test_foo[key2_name-val3_name]>
<Function test_boo[key2_name-val3_name]>
<Function test_foo[key2_name-val4_name]>
<Function test_boo[key2_name-val4_name]>
如何为该参数添加ids
?
这是一个解决方案,使用调用外部函数负责从参数值格式化名称。
def idfn(val):
# receive here each val
# so you can return a custom property
return val.name
@pytest.mark.parametrize(
"key, value",
[(k, v) for k, l in some_dict.items() for v in l],
scope="class",
ids=idfn,
)
class TestSomething:
def test_foo(self, key, value):
assert True
但是MrBean建议的使用lambda的简单解决方案也有效。在您的简单情况下,我会选择这个,只有在需要更复杂的格式时才使用外部函数。
@pytest.mark.parametrize(
"key, value",
[(k, v) for k, l in some_dict.items() for v in l],
scope="class",
ids=lambda val: val.name,
)
class TestSomething:
def test_foo(self, key, value):
assert True
可用的选项在文档
中给出。如果需要多对多映射,还有另一种(更好的)方法。您只需将两个装饰器一起使用即可。它可能不完全适合你的情况,因为你想要有一个字典,但我认为这种方式也是值得提及的,以防你决定在将来重构你的代码。
例如-
import pytest
@pytest.mark.parametrize("x", [1, 2, 3])
@pytest.mark.parametrize("y", [4, 5, 6])
def test_function(x, y):
assert x + y > 5
测试函数将以以下参数组合运行:
(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)