Search code examples
pythonpytestfixtures

pytest how to pass request fixture through intermediary fixture


I have (in pytest):

  • base fixture that uses request.param
  • intermediary fixture that uses the base fixture
  • Test that uses the intermediary fixture, and I want to parameterize the base fixture

The below code sample will help explain:

import pytest

@pytest.fixture
def base(request) -> int:
    return request.param

@pytest.fixture
def intermediary(base: int) -> int:
    return base

# This does not work!  "In test_something: indirect fixture 'base' doesn't exist"
@pytest.mark.parametrize("intermediary", [1], indirect=["base"])
def test_something(intermediary: int) -> None:
    assert isinstance(intermediary, int)

My question: how can I populate request of the base fixture, from a test that uses only the intermediary fixture?


Workaround

Including the base fixture in the test signature works:

@pytest.mark.parametrize("base", [1], indirect=True)
def test_something_workaround(base: int, intermediary: int) -> None:
    assert isinstance(intermediary, int)

However, this is undesirable to me, because the test doesn't actually use base, only intermediary.


Versions

Python==3.8
pytest==6.2.2

Solution

  • You can do it almost this way, but you have to use "base" as the fixture name in parametrize:

    @pytest.fixture
    def base(request) -> int:
        return request.param
    
    
    @pytest.fixture
    def intermediary(base: int) -> int:
        return base + 1
    
    
    @pytest.mark.parametrize("base", [1], indirect=True)
    def test_something(intermediary: int) -> None:
        assert intermediary == 2
    

    E.g. you parametrize fixture base, but use the derived fixture, which than gets the result from base.