2

I understand that pytest fixtures raise an error when calling a fixture directly from within a test. But I don't fully understand why. For context, I am a junior dev new to python so I may be missing something obvious that needs explaining.

I have a fixture as follows:

@pytest.fixture()
def get_fixture_data_for(sub_directory: str, file_name: str) -> json:
    file_path = Path(__file__).parent / f"{sub_directory}"
    with open(file_path / f"{file_name" as j:
        data = json.load(j)
    return data

and then a test that says something like

def test_file_is_valid():
    data = get_fixture_data_for('some_subdir', 'some_filename.json')
    #do something with this information
    ...

I have many different test files that will use this fixture function to read data from the files and then use the data in posting to an endpoint for integration tests.

When running this, I get the error that fixtures are not meant to be called directly, and should be created automatically when test functions request them as parameters. But why?

I see in the docs this is mentioned: https://docs.pytest.org/en/stable/deprecations.html#calling-fixtures-directly but I don't understand why this functionality was deprecated.

Tom
  • 93
  • 1
  • 1
  • 8
  • You should use the dependency injection and take the dependency as a argument instead – mousetail Sep 12 '22 at 14:02
  • 2
    This is just how fixtures work. Once you wrap a function with the fixture decorator, the function is replaced with a fixture which expects to be invoked only by the pytest test setup. This provides a large number of advantages. But you don’t have to use it. You could simply remove the fixture decorator and call the function as you are now if you like. – Michael Delgado Sep 12 '22 at 14:20
  • Micheal gave you a good suggestion but if you do need to use a fixture instead of just a simple function, you can use [indirect parametrization](https://docs.pytest.org/en/7.1.x/example/parametrize.html#indirect-parametrization) to pass some data to the fixture. – tmt Sep 13 '22 at 13:58
  • Thanks, I think my question comes from a lack of understanding of fixtures rather than anything pytest specific – Tom Sep 14 '22 at 10:26

1 Answers1

1

Answering my own question for any newbies that come across this in future. As Michael alluded to in the comment above - what I am trying to do is use a helper function as a fixture.

Fixtures are loaded and run once (depending on the scope you provide it) when the test suite is run. They are for setting up the test. For example, if you had a dict that needed populating and loading, that would then be passed into tests; this would be best handled by a fixture.

However, if you wanted to manipulate some data generated within the test, you would use a helper function - as this is not something used to set up the test.

Tom
  • 93
  • 1
  • 1
  • 8