indirect=True vs indirect=False in @pytest.mark.parametrize()?

26.6k views Asked by At

I just want to understand what it means or what happens if I set indirect parameter to True or False in the pytest.mark.parametrize?

2

There are 2 answers

5
Sergei Voronezhskii On BEST ANSWER

With indirect=True you can parametrize your fixture, False - default value. Example:

import pytest

@pytest.fixture
def fixture_name(request):
    return request.param

@pytest.mark.parametrize('fixture_name', ['foo', 'bar'], indirect=True)
def test_indirect(fixture_name):
    assert fixture_name == 'baz'

So this example generates two tests. First one gets from fixture_name value foo, because this fixture for this test runs with parametization. Second test gets bar value. And each tests will fail, because of assert checking for baz.

0
Super Kai - Kazuya Ito On

For example, indirect=False is set to @pytest.mark.parametrize() as shown below. *Actually, by default, indirect=False is set to @pytest.mark.parametrize() implicitly so you don't need to set indirect=False to it explicitly:

import pytest

@pytest.fixture
def fruits(request):
    return f'fruits {request.param}'

@pytest.mark.parametrize(
    "fruits", 
    ("Apple", "Orange", "Banana"), 
    indirect=False # Here
)
def test(fruits):
    print(fruits)
    assert True

Then, Apple, Orange and Banana are passed to test() directly as shown below. *Actually, fruits() fixture is not run:

$ pytest -q -rP
...                              [100%]
=============== PASSES ================ 
_____________ test[Apple] _____________ 
-------- Captured stdout call --------- 
Apple
____________ test[Orange] _____________ 
-------- Captured stdout call --------- 
Orange
____________ test[Banana] _____________ 
-------- Captured stdout call --------- 
Banana
3 passed in 0.10s

Now, indirect=True is set to @pytest.mark.parametrize() as shown below:

import pytest

@pytest.fixture
def fruits(request):
    return f'fruits {request.param}'

@pytest.mark.parametrize(
    "fruits", 
    ("Apple", "Orange", "Banana"), 
    indirect=True # Here
)
def test(fruits):
    print(fruits)
    assert True

Then, Apple, Orange and Banana are passed to test() indirectly through fruits() fixture as shown below. *Both test() and fruits() fixture are run:

$ pytest -q -rP
...                              [100%]
=============== PASSES ================ 
_____________ test[Apple] _____________ 
-------- Captured stdout call --------- 
fruits Apple
____________ test[Orange] _____________ 
-------- Captured stdout call --------- 
fruits Orange
____________ test[Banana] _____________ 
-------- Captured stdout call --------- 
fruits Banana
3 passed in 0.10s