pytest reuse fixture between projects

Viewed 1489

I want to create fixtures as library components.

A standard test database config is useful for several projects in different repos. It is currently copy/pasted into each independent project as they can't share a config.py.

I refactored the code into a pip installable library but can't work out an elegant way to use it in each project. This doesn't work:

import my_db_fixture

@pytest.fixture
def adapted_db_fixture(my_db_fixture):
    # adapt the test setup

For the real code, the fixture I want to re-use is built from other fixtures. The best work-around I can find so far is to create a local conftest.py as copy/paste code but limited to importing functions and calling them in local fixture functions. I don't like copy/paste and unnecessarily exposes the inner workings of the fixtures.

1 Answers

It is possible to re-use fixtures from an installed library.

Define the fixtures as usual in the installable package. Then import them into a conftest.py local to the project. You need to import not just the fixture you want but also all fixtures it depends on and (if used) pytest_addoption

from my.package import (
    the_fixture_i_want,
    all_fixtures_it_uses,
    pytest_addopt
)

I also discovered you can't un-decorate a library function with a teardown and call it in the local conftest.py:

# This doesn't work

# pip installed my_fixture.py
def my_fixture(dependencies)
    # setup code
    yield fixture_object
    # teardown code

# local conftest.py
import pytest
import my_fixture  # NB: the module

@pytest.fixture
def my_fixture(dependencies):
    my_fixture.my_fixture()
    # teardown code isn't called: pytest knows the function has no yield
    # but doesn't realise it's returning a generator none the less

This article helped me:

peterhurford/pytest-fixture-modularization.md

I reckoned pytest should recognise something returning a generator as a generator so logged it as a bug. I imagine comments responding to it could be useful:

call_fixture_func should test the return value not the function

Related