pytest mark parametrize a fixture

Question:

I want to test a function get_xyz(a, b, foo), where foo is a class. A foo_fixture is defined in a conftest.py like so:

@pytest.fixture()
def foo_fixture():
    return Foo()

The fixture simply returns a new instance of a class Foo. How would I parametrize this foo_fixture as an argument to test_get_xyz? I have tried the below code but it doesn’t work, also have read about using indirect=True in the parametrize decorator but also couldn’t get that to work properly…

@pytest.mark.parametrize("a,b,foo_fixture",
                         [1, 2, pytest.lazy_fixture('foo_fixture')]
                        )
def test_get_xyz(a, b, foo_fixture):
    get_xyz(a, b, foo_fixture)
Asked By: des224

||

Answers:

Here is implementation with indirect parametrize:

import pytest


class Foo:
    pass


@pytest.fixture
def foo_fixture():
    return Foo()


@pytest.mark.parametrize(
    "a, b, foo_fixture",
    [
        (1, 2, None),
        (3, 4, None),
        (5, 6, None),
    ],
    indirect=["foo_fixture"]
)
def test_get_xyz(a, b, foo_fixture):
    print("n", a, b, foo_fixture)

Output is:

PASSED                          [ 33%]
 1 2 <test_indirect.Foo object at 0x000002318A4084C0>
PASSED                          [ 66%]
 3 4 <test_indirect.Foo object at 0x000002318A408610>
PASSED                          [100%]
 5 6 <test_indirect.Foo object at 0x000002318A4086A0>

As you can see Foo is different instance in each test.

Read more about indirect parametrize.

Basically you just specify which of your parameters are fixtures and pass any value for it (None for example).

If you need to change something in fixture based on passed parameters then you will need to pass some value instead of None and grab it inside foo_fixture using request fixture like this:

@pytest.fixture
def foo_fixture(request):
    return Foo(request.param)
Answered By: pL3b
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.