I have an ETL build with sqlalchemy. To test it, we are using postgres in a docker container through pytest-docker.
But because on some computer, spinning docker container takes some time, we also have a sqlite backend.

The question is, how to conditionally select either backend without spinning the docker container with fixtures docker_ip and docker_services provided by pytest-docker?

I have the following:

@pytest.fixture(name="sqlite_db", scope="session")
def fixture_sqlite_db():
  ...
  yield engine


@pytest.fixture(name="postgres_db", scope="session")
def fixture_postgres_db(docker_ip, docker_services):
  ...
  yield engine


@pytest.fixture(name=mock_get_engine", scope="session")
def fixture_mock_get_engine(engine):
  with pytest.MonkeyPatch.context() as mock:
    mock.setattr(my_module, "get_engine", lambda: engine)
    yield mock 

So far, both engine fixtures were run in separate test files, with copy of all tests, with the postgres having:

if not os.getenv("TEST_POSTGRES", False):
    pytest.skip("skipping postgres database tests", allow_module_level=True)

which worked, but having half of the test-suite by copy-pasted is less than ideal.

---

Is there way to select fixture conditionally?

I tried:

@pytest.fixture(name="engine", scope="module")
def fixture_engine():
    if os.getenv("TEST_POSTGRES", False):
        engine = fixture_postgres_db()
    else:
        engine = fixture_sqlite_db()
    yield engine

but this didn't work.

Edit:

The build-in fixture request can be used for this. The parameterized documentation uses it in slightly different context, but never elaborates over it. Had to hard grok it :(

Using request.getfixturevalue, a fixture can be selected.

@pytest.fixture(name="engine", scope="module")
def fixture_engine(request):
    if os.getenv("TEST_POSTGRES", False):
        engine = request.getfixturevalue("postgres_db")
    else:
        engine = request.getfixturevalue("sqlite_db")
    yield engine

0

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.