The baseline of all my tests is that there will always be a taxi with at least one passenger in it. I can easily achieve this setup with some basic fixtures:
from blah import Passenger, Taxi
@pytest.fixture
def passenger():
return Passenger()
@pytest.fixture
def taxi(passenger):
return Taxi(rear_seat=passenger)
Testing the baseline is straightforward:
def test_taxi_contains_passenger(taxi)
assert taxi.has_passenger()
My issue crops up when I start needing more complicated test setup. There will be scenarios where I'll need the taxi to have more than one passenger and scenarios where I'll need to define passenger attributes. For example:
def test_three_passengers_in_taxi(taxi)
assert taxi.has_passengers(3)
assert taxi.front_passenger_is_not_a_child()
I'm able to get around this problem by having specific fixtures for specific tests. For the above test, I would create the following fixture:
@pytest.fixture
def three_passenger_test_setup(taxi)
taxi.add_front_seat_passenger(Passenger(child=False))
taxi.add_rear_seat_passenger(Passenger())
return taxi
I can pass the above fixture into my test case and everything is dandy, but if I go down this route I might end up with a fixture for every test and it feels like there should be a more efficient way of doing this.
Is there a way to pass arguments to a fixture so that those arguments can be used in creating the object the fixture returns? Should I be parameterizing the test function? The fixture? Or am I wasting time and is a fixture per test the way to go?
We can do this by using a method that takes args within a fixture and return the method from the fixture.
let me show you an example
@pytest.fixture
def my_fixture():
def _method(a, b):
return a*b
return _method
def test_me(my_fixture):
result1 = my_fixture(2, 3)
assert result1 == 6
result2 = my_fixture(4, 5)
assert result2 == 20