考虑以下Pytest:
import pytest
class TimeLine(object):
instances = [0, 1, 2]
@pytest.fixture
def timeline():
return TimeLine()
def test_timeline(timeline):
for instance in timeline.instances:
assert instance % 2 == 0
if __name__ == "__main__":
pytest.main([__file__])
考试 test_timeline
使用Pytest夹具, timeline
,它本身具有属性 instances
。此属性在测试中迭代,因此只有断言适用于每个时,测试才会通过 instance
在 timeline.instances
。
然而,我真正想要做的是生成3个测试,其中2个应该通过,其中1个将失败。我试过了
@pytest.mark.parametrize("instance", timeline.instances)
def test_timeline(timeline):
assert instance % 2 == 0
但这导致了
AttributeError: 'function' object has no attribute 'instances'
据我了解,在Pytest中,函数'变为'它的返回值,但在测试参数化时似乎还没有发生过。如何以理想的方式设置测试?
这实际上可以通过 间接参数化。
这个例子用pytest 3.1.2做你想要的:
import pytest
class TimeLine:
def __init__(self, instances):
self.instances = instances
@pytest.fixture
def timeline(request):
return TimeLine(request.param)
@pytest.mark.parametrize(
'timeline',
([1, 2, 3], [2, 4, 6], [6, 8, 10]),
indirect=True
)
def test_timeline(timeline):
for instance in timeline.instances:
assert instance % 2 == 0
if __name__ == "__main__":
pytest.main([__file__])
另见 这个类似的问题。
间接参数化的使用有效,但我发现需要使用 request.param
作为一个神奇的,未命名的变量有点尴尬。
这是我用过的模式。可以说,它以不同的方式尴尬,但也许你也会喜欢它!
import pytest
class TimeLine:
def __init__(self, instances):
self.instances = instances
@pytest.fixture
def instances():
return [0, 0, 0]
@pytest.fixture
def timeline(instances):
return TimeLine(instances)
@pytest.mark.parametrize('instances', [
[1, 2, 3], [2, 4, 5], [6, 8, 10]
])
def test_timeline(timeline):
for instance in timeline.instances:
assert instance % 2 == 0
该 timeline
夹具取决于另一个夹具 instances
,其默认值为 [0,0,0]
,但在实际测试中,我们使用 parametrize
为...注入一系列不同的值 instances
。
我认为它的优点是一切都有一个好名字,而且你不需要通过它 indirect=True
旗。
而不是间接参数化,或者我的涉及继承的hacky解决方案,你也可以只使用 params
论证 @pytest.fixture()
- 我认为这是最简单的解决方案吗?
import pytest
class TimeLine:
def __init__(self, instances=[0, 0, 0]):
self.instances = instances
@pytest.fixture(params=[
[1, 2, 3], [2, 4, 5], [6, 8, 10]
])
def timeline(request):
return TimeLine(request.param)
def test_timeline(timeline):
for instance in timeline.instances:
assert instance % 2 == 0
https://docs.pytest.org/en/latest/fixture.html#parametrizing-fixtures