Skip to content

Testcontainers

Real databases, brokers and services in Docker containers, started by your tests.

TestingJava

What it is

Testcontainers is a Java library that provides lightweight, disposable Docker containers for running integration tests. It allows developers to test against databases, message brokers, or any containerized service in a reproducible way.

Testcontainers allows developers to spin up Docker containers for databases, message queues, or other services during test execution. It supports JUnit 5 extensions, lifecycle management, reusable containers, and pre-configured modules for common services like PostgreSQL, MySQL, Kafka, and Redis.

Licence
MIT
Best known for
Ending the 'works on H2, fails on Postgres' class of bug

When to use it

The question documentation cannot answer for you — because it cannot recommend something else.

Reach for it when

  • Integration tests that should run against the actual database, not an in-memory substitute
  • You have been burned by H2 behaving differently from PostgreSQL in production

Look elsewhere when

  • Docker is unavailable in your CI environment
  • Fast unit tests — container startup costs seconds, so keep these tests in a separate suite

Installation

Add org.testcontainers:testcontainers dependency in pom.xml

Getting started

The smallest useful thing you can do with it, and what each part means.

Starting a PostgreSQL container
import org.testcontainers.containers.PostgreSQLContainer;

PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15.3")
    .withDatabaseName("testdb")
    .withUsername("user")
    .withPassword("password");
postgres.start();
Starts a PostgreSQL container with a database name, username, and password for integration testing.
Using container JDBC URL
String jdbcUrl = postgres.getJdbcUrl();
String username = postgres.getUsername();
String password = postgres.getPassword();
Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
Retrieves connection details from the container to connect your application to the test database.

Advanced usage

Where the library earns its place over a simpler alternative.

JUnit 5 integration with @Testcontainers and @Container
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
public class MyDatabaseTest {

    @Container
    public static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15.3");

    @Test
    void testDatabaseConnection() {
        assertNotNull(postgres.getJdbcUrl());
    }
}
Uses annotations to automatically manage container lifecycle with JUnit 5 tests.
Reusable containers
postgres.withReuse(true);
// container can be reused across multiple test runs for faster execution
Enables container reuse to reduce startup time during repeated test executions.
Using Testcontainers for Kafka
import org.testcontainers.containers.KafkaContainer;
KafkaContainer kafka = new KafkaContainer("confluentinc/cp-kafka:7.6.1");
kafka.start();
Starts a Kafka container for testing messaging functionality in applications.
Custom container configuration
postgres.withInitScript("init.sql").withExposedPorts(5432);
Demonstrates how to initialize a container with a custom SQL script and expose ports.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Docker not found
Ensure Docker is installed and running on your system before running Testcontainers.
Container startup timeout
Increase startup timeout or verify the Docker image is available and compatible.
Networking issues connecting to container
Check Docker network configuration and exposed ports; ensure the test code uses the container's dynamic ports.

Best practices

  • Use `@Testcontainers` and `@Container` annotations for automatic lifecycle management.
  • Prefer lightweight containers for faster test execution.
  • Reuse containers when possible to reduce startup time.
  • Externalize configuration and credentials to environment variables for security.
  • Combine Testcontainers with JUnit 5 for seamless integration testing in CI/CD pipelines.

Alternatives

Comparable options, and the reason you would pick one over the other.

Background

Why it exists, and what it was reacting to.

Testcontainers was created to simplify integration testing by providing real, isolated environments using Docker containers. It eliminates the need for complex local setup and ensures tests run consistently across different machines and CI environments.