Clean • Professional
Testcontainers is a Java library that allows you to run real databases and external services inside Docker containers during Spring Boot tests. Instead of using in-memory databases or mocks, Testcontainers helps you test applications in a production-like environment.
It is widely used for integration testing to ensure your application behaves the same way in testing as it does in production.
Testcontainers automatically starts temporary Docker containers for required services—such as databases, message brokers, and caches—during test execution and shuts them down once tests complete.
This provides:
Example: How Testcontainers Works in a Test
The example below shows how Testcontainers starts a PostgreSQL Docker container automatically when the test runs.
@Testcontainers
@SpringBootTest
classUserRepositoryTest {
@Container
static PostgreSQLContainer<?> postgres =
newPostgreSQLContainer<>("postgres:15")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
@Test
voidcontextLoads() {
// Testcontainers automatically:
// 1. Starts PostgreSQL in Docker
// 2. Runs the test
// 3. Stops and removes the container
}
}
Testcontainers improves test reliability by using real infrastructure instead of mocks.
Key Benefits
Testcontainers is commonly used to test applications with real infrastructure components instead of mocks or in-memory services. It helps ensure your application behaves correctly in production-like environments.
| Component | Containers | Use Case Explanation |
|---|---|---|
| Database | PostgreSQL, MySQL, MongoDB | Test real database queries, schema migrations, indexes, and vendor-specific behavior |
| Messaging | Kafka, RabbitMQ | Validate event publishing, message consumption, retries, and message ordering |
| Cache | Redis | Test caching logic, expiration, session handling, and distributed locks |
| External APIs | WireMock | Simulate third-party APIs and test failure scenarios without calling real services |
| Full Stack | Multiple containers together | Test complete application flows with database, cache, and messaging running together |
PostgreSQL Testcontainers run a real Postgres database during tests, allowing accurate validation of database behavior.
What You Can Test
PostgreSQL Testcontainer Example
@Testcontainers
@SpringBootTest
classUserRepositoryTest {
@Container
static PostgreSQLContainer<?> postgres =
newPostgreSQLContainer<>("postgres:15")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
@DynamicPropertySource
staticvoidoverrideProps(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
}
Kafka Testcontainers allow you to test event-driven architectures using a real Kafka broker.
Example: Kafka Testcontainer
@Container
static KafkaContainer kafka =
new KafkaContainer(
DockerImageName.parse("confluentinc/cp-kafka:7.5.0")
);
registry.add(
"spring.kafka.bootstrap-servers",
kafka::getBootstrapServers
);
Redis Testcontainers is used to test caching, session management, and distributed locking in Spring Boot applications.
Example: Redis Testcontainer
@Container
static GenericContainer<?> redis =
newGenericContainer<>("redis:7")
.withExposedPorts(6379);
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
Spring Boot 3.1+ provides automatic Testcontainers integration, reducing configuration overhead.
spring.testcontainers.enabled=true
spring.datasource.url=jdbc:tc:postgresql:15:///testdb
@Testcontainers
@SpringBootTest
classUserRepositoryIT {
@Container
static PostgreSQLContainer<?> postgres =
newPostgreSQLContainer<>("postgres:15");
}
Benefits
The container lifecycle in Testcontainers defines when containers start and stop during test execution. Choosing the right lifecycle helps balance test speed, isolation, and reliability.
| Scope | Behavior | When to Use |
|---|---|---|
static @Container | One container is started once per test class and shared by all test methods | Faster tests when all methods can share the same database |
Non-static @Container | A new container is started for every test method | Maximum isolation and clean state for each test |
| Reusable Containers | Containers are reused across multiple local test runs | Faster local development and repeated test execution |
Reusable containers allow Testcontainers to reuse the same Docker container across multiple test runs on your local machine. This significantly reduces test startup time during development.
Step 1: Enable reuse in configuration
Add the following line to your local Testcontainers configuration file:
testcontainers.reuse.enable=true
Step 2: Mark the container as reusable
.withReuse(true)
Use Testcontainers when:
Avoid Testcontainers for:
| Feature | Testcontainers | H2 |
|---|---|---|
| Database Type | Real (Postgres, Kafka, Redis) | In-memory |
| Speed | Slower | Very fast |
| Accuracy | Production-level | Limited |
| Best For | Integration testing | Repository testing |
Testcontainers enables real, production-like integration testing in Spring Boot by running actual services like PostgreSQL, Kafka, and Redis in Docker. It helps catch real-world issues early, ensures consistent behavior across environments, and makes applications more reliable and production-ready.