
2.3k stars · Apache-2.0 | [testcontainers-python.readthedocs.io](https://testcontainers-python.readthedocs.io/en/latest/) · testcontainers-v4.15.0 (2026-07-24) · Track this in Rising ↗
Tests get a real, empty PostgreSQL, started and destroyed automatically.
Radar check
What we found when we opened it. Every bar is one fact, with its date.
Last code pushed 9 Oct 2026, 18 days before this check.
Latest release testcontainers-v4.15.0 on 24 Jul 2026.
Public since March 2017, a little over 9 years.
2,319 stars and 394 forks.
26 commits and 12 new issues in the last 90 days.
191 contributors. 26 pull requests merged in 90 days.
No security policy file says how to report a problem. No published security advisories.
How the bars are scored
- Alive. Days since the last code push: a week or less 100, a month 90, three months 70, six months 50, a year 30, eighteen months 15, older 0.
- Releases. Age of the latest GitHub release, on a similar scale; no bar when the project publishes no releases.
- Maturity. Age of the project: eight years 100, five 90, three 70, two 55, one 40, six months 25, younger 10.
- Adoption. Stars on a log scale: 100,000 stars is 100, 10,000 is 80, 1,000 is 60, 100 is 40.
- Activity. Commits in the last 90 days: 300 or more 100, 100 85, 30 65, 10 45, any 25.
- Community. People who have contributed: 100 or more 100, 30 80, 10 60, 5 40, 2 25, one 10.
- Security. A published security policy 80, none 40; published advisories are listed, not scored.
Checked by Repo Radar on 27 Oct 2026 from the repository on GitHub. Covered in Edition 18.
▶Repo detailsthe review · specs · pros & cons · install
What it does
Testcontainers for Python is a library added to test code. It starts real services inside Docker containers for the length of a test run, waits until each one is ready, hands the test the address to connect to, and removes them when the run ends. It covers far more than databases: more than forty services are packaged, including PostgreSQL, MySQL, Redis, Kafka, RabbitMQ, Elasticsearch and S3-compatible storage. Each container can be reused across a whole test session or started fresh per test. It works with pytest and with the standard library's own test runner. A clean-up helper removes containers even when a test run is killed halfway. Version 4.15.0 arrived on 24 July 2026. It does not provide the tests themselves, and it will not run where Docker is unavailable.
Why it matters
Who it suits. It suits anyone with a real database behind an application who has been putting tests off, because this removes the usual excuse. The common alternative is testing against SQLite, a small file-based database, and hoping it behaves like the real engine; it does not, and the differences appear in production. It also suits a team using a coding assistant to write tests, since tests against the real engine actually prove something. Skip it if Docker cannot be installed where the tests run, and skip it if a few seconds of extra time per test run matters more than accuracy.
Verdict. Worth an hour to adopt and almost nothing to maintain. Two things to expect. The first run downloads container images and is slow, and every run after that adds a few seconds. And Docker has to exist wherever the tests run, including on any build machine used later. The newest thing published on the GitHub releases page can be a release candidate, which is a version offered for testing, so install from PyPI where 4.15.0 is the finished release. Edition 17 covered electric-sql/pglite, which gives a browser a Postgres engine with no server at all, and the two sit neatly beside each other.
Summary (Key Points)from the README
Key features
- Container-based testing: Runs Docker containers for functional and integration tests.
- Postgres example: The README's snippet starts a PostgreSQL database in a container and queries its version.
- SQLAlchemy URL helper: `get_connection_url()` returns a SQLAlchemy-compatible URL for connecting to the container's database.
- Ryuk cleanup: Ryuk reaps dangling containers if its TCP connection is lost past the reconnection timeout.
- Socket override: `TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE` sets the Docker socket path used by Ryuk, defaulting to `/var/run/docker.sock` in the example.
- Custom Ryuk image: `RYUK_CONTAINER_IMAGE` replaces the default image, shown as `testcontainers/ryuk:0.8.1`.
- Reconnection timeout: `RYUK_RECONNECTION_TIMEOUT` defaults to `10s` in the example.
- Runtime configuration: The README says behaviour can also be set at runtime, alongside environment variables.
Important
- Ryuk can be disabled: Setting `TESTCONTAINERS_RYUK_DISABLED` to true turns off Ryuk, so containers may not be cleaned up automatically.
- Privileged Ryuk option: `TESTCONTAINERS_RYUK_PRIVILEGED` runs Ryuk as a privileged container; it defaults to false.
- Docker socket dependency: The configuration relies on a Docker socket path, so a reachable Docker daemon is needed.
- Runtime setup not shown: The README mentions runtime configuration but does not show how to do it in the text provided.
- Detailed docs are external: Full usage details are in the separate documentation site, not in the README.
Written by an AI model from the project’s README; not part of the review, and it can be wrong.
- Tests run against the same database engine as production, so a passing test means more.
- Every run starts empty, so tests cannot pollute each other.
- More than forty services are packaged, not only databases.
- The first run pulls container images and is slow, and later runs still add seconds.
- Docker has to be available wherever the tests run, including on build machines.
- The GitHub releases page can show a release candidate, so PyPI is the safer source.
cd ~/myapp source venv/bin/activate pip install "testcontainers[postgres]" pytest
