Can I pass arguments to pytest fixtures? Can I pass arguments to pytest fixtures? python python

Can I pass arguments to pytest fixtures?


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.fixturedef my_fixture():  def _method(a, b):    return a*b  return _methoddef test_me(my_fixture):  result1 = my_fixture(2, 3)  assert result1 == 6  result2 = my_fixture(4, 5)  assert result2 == 20


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?

You can use test parametrization with indirect=True.In the pytest docs: Apply indirect on particular arguments. As displayed here: https://stackoverflow.com/a/33879151/3858507


The fixture?

Another option that might suit you is using some fixture that specifies the argument using parametrization:

@pytest.fixture(params=[3,4])def number_of_passengers(request):    return request.param

and then accessing this fixture from the taxi and the test itself:

@pytest.fixturedef taxi(number_of_passengers):    return Taxi(rear_seat=Passenger() * number_of_passengers)def test_three_passengers_in_taxi(taxi, number_of_passengers)    assert taxi.has_passengers(number_of_passengers)    assert taxi.front_passenger_is_not_a_child()

This way is good if your tests and asserts are very similar between the cases you have.


Or am I wasting time and is a fixture per test the way to go?

I'd say you definitely shouldn't create a fixture for every test function. For that, you can just put the setup inside the test. This is actually a viable alternative in the case that you have to make different asserts for different cases of the taxi.


And finally another possible pattern you can use is a taxi factory. While for the example you've presented its not quite useful, if multiple parameters are required and only some are changing you can create a fixture similar to the following:

from functools import partial@pytest.fixturedef taxi_factory():    return partial(Taxi, 1, 2, 3)


That fixture is just a Python decorator.

@decoratordef function(args):  ...

is fancy for

def function(args):  ...function = decorator(function)

So you just might be able to write your own decorator, wrapping up the function you want to decorate in whatever you need and the fixture:

def myFixture(parameter):  def wrapper(function):    def wrapped(*args, **kwargs):      return function(parameter, *args, **kwargs)    return wrapped  return pytest.fixture(wrapper)@myFixture('foo')def function(parameter, ...):  ...

This will act like the fixture but will pass a value ('foo') as parameter to function.