Search code examples
pythonpytestfixturespytest-django

How to override a pytest fixture calling the original in pytest 4


I am defining a pytest fixture that to overrides the django_db_setup fixture.

The change I have sets up additional teardown for safety, as there are integration tests that use this fixture which may spawn processes and cleanup is sometimes required to keep all things from breaking.

This seems reasonable, and is also suggested in pytest docs. However, I don't want to copy paste the same exact logic of django_db_setup since I'm happy with what is already there. Running it as a function, however, raises a deprecation warning:

/usr/local/lib/python3.6/dist-packages/_pytest/fixtures.py:799:

 RemovedInPytest4Warning: Fixture "django_db_setup" called directly.
 Fixtures are not meant to be called directly, are created automatically
 when test functions request them as parameters. See
 https://docs.pytest.org/en/latest/fixture.html for more information.

What would be the recommended way to deal with this situation in pytest 4? Are we encouraged to copy-paste code from fixtures we want to override, or is there another way to "inherit" a fixture, and inject e.g custom behavior before as well as after it is called?


Solution

  • To inject custom behavior before the initial fixture is called you can create separate fixture with this behavior and use it before the initial fixture in parameter list of fixture that overrides previously defined:

    @pytest.fixture(scope='session')
    def inject_before():
        print('inject_before')
    
    @pytest.fixture(scope='session')
    def django_db_setup(inject_before, django_db_setup):
        print('inject_after')