Search code examples
pythonpytestfixtures

pytest access parameters from function scope fixture


Let's assume I have the following code:

@pytest.mark.parametrize("argument", [1])
def test_func(self, function_context, argument)

And I have the following function scope fixture:

@pytest.fixture(scope='function')
def function_context(session_context):
    # .... do something ....

Is it possible to access the current function argument from within the function_context fixture?

In my case - I want to get the value 1 that is being passed in parametrize from within function_context.


Solution

  • Fixtures in pytest are instantiated before the actual tests are ran, so it shouldn't be possible to access the test function argument at the fixture definition stage. However, I can think of two ways to bypass this:

    1. Monkeypatching

    You can monkeypatch the fixture, i.e. temporarily change some of its attributes, based on the parameter of the function that uses this fixture. For example:

    @pytest.fixture(scope='function')
    def function_context(session_context):
        # .... do something ....
    
    @pytest.mark.parametrize("argument", [1])
    def test_func(self, function_context, argument, monkeypatch):
        monkeypatch.setattr(function_context, "number", argument) # assuming you want to change the attribute "number" of the function context
        # .... do something ....
    

    Although your fixture is valid for the scope of the function only anyhow, monkeypatching is also only valid for a single run of the test.

    2. Parametrizing the fixture instead of the test function

    Alternatively, you can also choose to parametrize the fixture itself instead of the test_func. For example:

    @pytest.fixture(scope='function', params=[0, 1])
    def function_context(session_context, request):
        param = requests.param # now you can use param in the fixture
        # .... do something ...
    
    def test_func(self, function_context):
        # .... do something ...