ConfigsApr 15, 2026·3 min read

Testcontainers — Throwaway Docker Dependencies for Integration Tests

Language libraries that spin up real Postgres, Kafka, Redis, Selenium, and any Docker image for integration tests — then throw them away.

TL;DR
Testcontainers spins up real databases and services in Docker for reliable integration tests.
§01

What it is

Testcontainers is a set of language libraries that spin up real Docker containers for integration tests. Instead of mocking Postgres, Kafka, Redis, Selenium, or Elasticsearch, you run the actual service in a throwaway container that starts before your test and is destroyed after. Testcontainers supports Java, Python, Go, Node.js, .NET, and Rust.

Testcontainers is for backend developers who write integration tests and want to test against real databases and services without maintaining a shared test environment.

The project is actively maintained with regular releases and a growing user community. Documentation covers common use cases, and the open-source nature means you can inspect the source code, contribute fixes, and adapt the tool to your specific requirements.

§02

How it saves time or tokens

Mocks drift from real behavior. Shared test databases cause flaky tests from data contamination. Testcontainers gives each test run a fresh, isolated instance of the real service. Tests are deterministic and run anywhere Docker is available -- local machines, CI/CD, and containers-in-containers setups.

§03

How to use

  1. Add the Testcontainers library to your project's test dependencies.
  2. Declare which containers your tests need.
  3. Testcontainers starts the containers before tests and destroys them after.
§04

Example

// Java (JUnit 5)
@Testcontainers
class OrderRepoTest {

    @Container
    static PostgreSQLContainer<?> pg = new PostgreSQLContainer<>("postgres:16");

    @Test
    void shouldSaveOrder() {
        var ds = new PGSimpleDataSource();
        ds.setUrl(pg.getJdbcUrl());
        ds.setUser(pg.getUsername());
        ds.setPassword(pg.getPassword());

        // Test with real PostgreSQL
        var repo = new OrderRepo(ds);
        repo.save(new Order("item-1", 42));
        assertEquals(1, repo.count());
    }
}
# Python
from testcontainers.postgres import PostgresContainer

def test_with_postgres():
    with PostgresContainer('postgres:16') as pg:
        conn = pg.get_connection_url()
        # Test with real PostgreSQL
§05

Related on TokRepo

§06

Common pitfalls

  • Testcontainers requires Docker to be running. CI/CD pipelines without Docker-in-Docker support or privileged mode will fail to start containers.
  • Container startup adds time to tests. Use @Container with static (Java) or module-scoped fixtures (Python) to reuse containers across test methods.
  • Port mapping is dynamic. Never hardcode ports; always use the container object's methods to get the mapped port.

Before adopting this tool, evaluate whether it fits your team's existing workflow. Read the official documentation thoroughly, and start with a small proof-of-concept rather than a full migration. Community forums, GitHub issues, and Stack Overflow are valuable resources when you encounter edge cases not covered in the documentation.

Frequently Asked Questions

Which languages does Testcontainers support?+

Testcontainers has libraries for Java, Python, Go, Node.js, .NET, and Rust. Each library provides language-idiomatic APIs for managing containers in tests.

Does Testcontainers work in CI/CD?+

Yes. Testcontainers works in any CI/CD environment that supports Docker. GitHub Actions, GitLab CI, CircleCI, and Jenkins all support Testcontainers. Docker-in-Docker or socket mounting may be required.

Can I use Testcontainers with any Docker image?+

Yes. Testcontainers provides a GenericContainer class that works with any Docker image. Pre-built modules for popular services (PostgreSQL, Kafka, Redis) add convenience methods for connection strings and readiness checks.

How does Testcontainers clean up containers?+

Testcontainers automatically stops and removes containers when tests complete. It also runs a 'Ryuk' sidecar container that garbage-collects orphaned test containers if the test process crashes.

Does Testcontainers support Docker Compose?+

Yes. Testcontainers has a Docker Compose module that starts an entire docker-compose.yml stack for integration tests. This is useful for testing multi-service architectures.

Citations (3)

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets