pytest-docker
Pytest fixtures that spin up Docker Compose services for integration tests, then tear them down automatically.
Repository Health
Technical Analysis
pytest-docker is a small pytest plugin that turns a docker-compose.yml file into a set of ready-to-use fixtures for integration testing. Point it at your compose file and it will bring the defined services up before your tests run, wait for them to report healthy via --wait (or a custom readiness check you write), hand your tests the resolved host/port for each container, and tear everything down again once the session ends.
It was built for the common case where an integration test suite needs a real database, cache, or HTTP service running in Docker rather than a mock. Instead of hand-rolling subprocess calls to docker compose in a conftest.py, teams install the plugin, register it as a pytest11 entry point (automatic once installed), and override a handful of well-named fixtures — docker_compose_file, docker_compose_project_name, docker_setup, docker_cleanup — only where the defaults don’t fit. It supports both Docker Compose V2 (docker compose, the default) and the deprecated V1 docker-compose binary via an extra.
What You Get
- A
docker_servicesfixture that runsdocker compose up --build --waitbefore the session anddocker compose down -vafter it, scoped by default to the whole test session - A
docker_ipfixture that resolves the correct host address for reaching containers, accounting for remoteDOCKER_HOSTsetups port_for(service, container_port)to look up the host-mapped port for any service/port pair defined in the compose file, with an internal cache so repeated calls are freewait_until_responsive(check, timeout, pause)to poll a custom readiness callable until a service accepts connections or the timeout is hit- A
--container-scopeCLI flag plus acontainer_scope_fixtureso fixture scope (session/module/class) is configurable without editing test code - Override points (
docker_compose_file,docker_compose_project_name,docker_setup,docker_cleanup,docker_compose_command) so any part of the compose lifecycle can be customized inconftest.py
Common Use Cases
- Running integration tests against a real Postgres/Redis/HTTP service defined in a project’s
docker-compose.ymlwithout a separate CI script to manage the stack - Verifying an HTTP service is actually reachable before tests hit it, using
wait_until_responsivetogether with a plainrequests.gethealth check - Pinning a fixed compose project name so a test suite re-run from an IDE tears down a stale stack before starting a fresh one, instead of accumulating duplicate containers
- Composing multiple compose files (e.g. a base stack plus a test-specific override) by returning a list of paths from the
docker_compose_filefixture - Supporting teams still on Docker Compose V1 by swapping the
docker_compose_commandfixture todocker-composeand installing thedocker-compose-v1extra
Under The Hood
Architecture
The plugin is a single module (src/pytest_docker/plugin.py) re-exported through __init__.py, which also registers the --container-scope CLI option via pytest_addoption and is wired up as a pytest11 entry point in setup.cfg so pytest auto-loads it on install. The core lifecycle lives in get_docker_services, a contextlib.contextmanager that builds a frozen DockerComposeExecutor (an attrs-based value object wrapping the compose command, file list, and project name), runs the configured docker_setup commands, yields a frozen Services object for the test session, and always runs docker_cleanup commands in a finally block regardless of test outcome. Every configurable piece — command, compose file(s), project name, setup/cleanup commands — is its own small pytest fixture, so overriding one behavior in a conftest.py doesn’t require touching the plugin’s internals; this fixture-per-concern layering is the one thing that would need to change if the compose invocation model itself changed.
Tech Stack
Pure Python 3.8+, packaged with legacy setuptools/setup.cfg metadata behind a minimal pyproject.toml build-system declaration. Runtime dependencies are deliberately tiny: pytest (>=4.0,<10.0) for the fixture/plugin machinery and attrs (>=19.2.0) for immutable value objects (Services, DockerComposeExecutor). An optional docker-compose-v1 extra pins the legacy docker-compose CLI for teams not yet on Compose V2. Shelling out to docker compose/docker-compose itself happens via subprocess.check_output, not a Docker SDK. CI runs on GitHub Actions with a separate publish workflow for PyPI releases.
Code Quality
The test suite (tests/) mixes direct fixture-value assertions (e.g. asserting docker_compose_command resolves to "docker compose") with pytest’s own pytester/testdir fixtures to run the plugin against synthetic test files it generates on the fly, letting the suite exercise real fixture-scope behavior (--container-scope=session|module|class) end to end rather than just unit-testing helper functions. plugin.py carries type hints throughout (Dict, Union, Optional, Iterator) and the project enforces mypy --strict, pylint, and pycodestyle as pytest plugins invoked via addopts in setup.cfg, so a normal pytest run doubles as the lint/type gate; all three are also wired into CI. No dedicated docs/ folder or CONTRIBUTING file exists — the README carries setup, override, and contribution guidance in one document.
API Design
The public surface is deliberately small and idiomatic to pytest: five fixtures plus a Services helper class, all overridable using pytest’s normal fixture-shadowing convention rather than a bespoke plugin-configuration format. Sensible defaults (docker compose, tests/docker-compose.yml, session scope, up --build --wait/down -v) mean a project with a compose file already in the conventional location needs zero configuration to get a working docker_services fixture; less common needs (multiple compose files, V1 compose, custom project naming to avoid stale-stack collisions) are each a one-fixture override documented directly in the README with a runnable snippet.
Used by 3 apps in this directory
Airbyte
Developer Tools · Data Engineering
Open-source ELT platform with 600+ connectors for moving data from any source to warehouses, lakes, and AI agents.
Keep
Devops · Automation · Monitoring
The open-source AIOps and alert management platform that unifies 130+ monitoring tools into a single pane of glass with AI-powered correlation, deduplication, and workflow automation.
Open WebUI
AI Assistants · AI Agents
The extensible, privacy-first AI platform that runs Ollama, OpenAI, and any LLM backend behind a polished, feature-packed web interface.