Consider the following 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__])
The test test_timeline
uses a Pytest fixture, timeline
, which itself has the attribute instances
. This attribute is iterated over in the test, so that the test only passes if the assertion holds for every instance
in timeline.instances
.
What I actually would like to do, however, is to generate 3 tests, 2 of which should pass and 1 of which would fail. I've tried
@pytest.mark.parametrize("instance", timeline.instances) def test_timeline(timeline): assert instance % 2 == 0
but this leads to
AttributeError: 'function' object has no attribute 'instances'
As I understand it, in Pytest fixtures the function 'becomes' its return value, but this seems to not have happened yet at the time the test is parametrized. How can I set up the test in the desired fashion?
You can use such a simple parametrized fixture for more complex fixtures by combining the param value with some kind of factory. You can also alias the call to parametrize: numbers = pytest. mark.
Generally, the parameter can be any object, so you can always put your fixture parameters in a suitable object. With a tuple or a list parameter, you can also access the values per index as in your example.
You can pass arguments to fixtures with the params keyword argument in the fixture decorator, and you can also pass arguments to tests with the @pytest.
This is actually possible via indirect parametrization.
This example does what you want with 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__])
Also see this similar question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With