Local import as pytest fixture?

Viewed 29

I need to import some functions locally within my tests (yes, the code base can be designed better to avoid this necessity, but let's assume we can't do that).

That means the first line of all my tests within a module looks like in this example:

def test_something():
    from worker import process_message

    process_message()

Now I wanted to make this more DRY by creating the following fixture:

@pytest.fixture(scope="module", autouse=True)
def process_message():
    from worker import process_message
    return process_message

But I always get the error

Fixture "process_message" called directly. Fixtures are not meant to be called directly, but are created automatically when test functions request them as parameters. See https://docs.pytest.org/en/stable/explanation/fixtures.html for more information about fixtures, and https://docs.pytest.org/en/stable/deprecations.html#calling-fixtures-directly about how to update your code.

The linked documentation doesn't help me much.

How can I achieve what I want? I'd like to return the function handle obviously.

1 Answers

The reason this happens is that you are calling the fixture directly from one of your tests. I assume that your test code with the fixture looks something like this:

import pytest


@pytest.fixture(scope="module", autouse=True)
def process_message():
    from worker import process_message
    return process_message


def test_something():
    process_message()

And then test_something fails with the specified exception.

The way to fix it is to add process_message as an argument to the test function, indicating that you are using it as a fixture:

def test_something(process_message):
    process_message()

btw, since you have to specify process_message fixture in every test in order to call it, means there is no point in using the autouse=True and it can be removed.

Related