Vince
Vince

Reputation: 4439

pytest fixture with argument

It seems it it possible to pass argument to fixtures:

Pass a parameter to a fixture function

yet, when implementing this minimal example, I get an error.

import pytest

@pytest.fixture
def my_fixture(v):
    print("fixture in")
    yield v+1
    print("fixture out")

@pytest.mark.parametrize("my_fixture",[1], indirect=True)
def test_myfixture(my_fixture):
    print(my_fixture)

@pytest.fixture def my_fixture(v): E fixture 'v' not found

Is anything wrong with the code above ?

(python 3.8.10, pytest-6.2.5)

Upvotes: 3

Views: 11188

Answers (3)

Kale Kundert
Kale Kundert

Reputation: 1504

To briefly elaborate on Vince's answer: in general, arguments to fixture functions are interpreted as the names of other fixtures to load before the one being defined. That's why you got the error message fixture 'v' not found: pytest thought that you wanted my_fixture to depend on another fixture called v that doesn't exist.

The request argument is an exception to this general rule. It doesn't refer to another fixture. Instead, it instructs pytest to give the fixture access to the request object, which contains information on the currently running test, e.g. which parameters are being tested (via request.param), which markers the test has (via request.node.get_closest_marker()), etc.

So to make use of indirect parametrization, your fixture needs to (i) accept the request argument and (ii) do something with request.param. For more information, here are the relevant pages in the documentation:

Upvotes: 7

Vince
Vince

Reputation: 4439

This works:

@pytest.fixture
def my_fixture(request):
    print("fixture in")
    yield request.param+1 # difference here !
    print("fixture out")

@pytest.mark.parametrize("my_fixture",[1], indirect=True)
def test_myfixture(my_fixture):
    print(my_fixture)


Upvotes: 6

Valentin Goldité
Valentin Goldité

Reputation: 1219

There is nothing wrong. Fixtures are used to fix constants to reuse them identically in multiple tests. They don't accept any argument. By the way you can create a pytest.fixture that is a "constant" function:

@pytest.fixture
def my_fixture():
    return lambda x: x+1

And avoid print in fixture (on the final version at least).

Upvotes: 1

Related Questions