Writing integration and functional tests that depend on databases is important but not easy.

Many teams run integration tests against a shared development or staging database, although that can create weird dependencies on the current state of the database or cause hard-to-diagnose test interleaving bugs.

A common alternative is to run a containerized database for each developer, either locally or on a testing cluster. The CI process can share the same process but use a dedicated database.

Intuitively, that means starting a Docker container running Postgres, MySQL, etc. and connecting to the container during test execution.

I’m most interested in testing Python applications, especially using pytest, which I prefer over unittest.

How should you manage your Docker containers? You could just use the Docker Python SDK. Lars Kellogg-Stedman describes that approach in his blog post “Managing containers with Pytest fixtures”.

If you don’t want to use the Docker SDK directly, a number of libraries have been built specifically to manage Docker containers during testing of Python modules:

  1. pytest-docker
  2. testcontainers-python
  3. pytest-docker-tools

I haven’t explored these tools in depth yet, although pytest-docker looks the most mature. Notably, unlike the others, pytest-docker relies on docker compose rather than base Docker. In an environment that already defines a compose.yaml, that may be particularly appealing.