Reputation: 2498
This question is similar to How to Parametrize a Pytest Fixture but I'd like to go a step further. Here's what I have so far:
import pytest
class TimeLine:
def __init__(self, s, instances=[0, 0, 0]):
self.s = s
self.instances = instances
@pytest.fixture(params=[
('foo', [0, 2, 4, 0, 6]),
('bar', [2, 5]),
('hello', [6, 8, 10])
])
def timeline(request):
return TimeLine(request.param[0], request.param[1])
This works
def test_timeline(timeline):
for instance in timeline.instances:
assert instance % 2 == 0
I would like to create a parameterized test for the length of instances
.
@pytest.mark.parametrize('length', [
(5), (1), (3)
])
def test_timeline(length, timeline):
assert len(timeline.instances) == length
There should be 3 tests. The first and the last tests should pass. The second test should fail. How would I set up the test to do this?
Upvotes: 0
Views: 968
Reputation: 710
I'll note that @pytest.mark.parameterize does exactly the same thing as the parameterized fixture you set up: runs the test once for each parameter. Therefore, I never use it because the indentation gets out of control with any sort of nested structure. I use this template:
well_named_params = [1,2,3] # I move this outside to avoid information overload.
@pytest.fixture(
params=well_named_params,
ids=["one","two","three"] # test label
)
def some_param(request):
""" Run the test once for each item in params.
Ids just provide a label for pytest. """
return request.param
Your code is good, but you need a comma after the numbers to denote a tuple. Should be (5,), (1,), (3,). I'm not 100% sure that each entry needs to be iterable, so if that doesn't work, try just removing the parenthesis.
Upvotes: 1