Spring Boot Testcontainers: Integration Testing Guide for 2026

Spring Boot Testcontainers: Integration Testing Guide

Spring Boot Testcontainers has transformed how developers write integration tests in modern Java applications. Therefore, instead of relying on mocked dependencies or shared test databases, you can now spin up real services in Docker containers during your test lifecycle. This approach catches bugs that unit tests simply cannot detect.

Why Integration Testing Needs Real Dependencies

Unit tests verify individual methods in isolation, but they miss issues at system boundaries. Moreover, mocking a database driver hides SQL dialect differences and constraint violations. As a result, many teams discover integration bugs only in staging or production environments.

Furthermore, in-memory databases like H2 behave differently from PostgreSQL or MySQL in production. Consequently, tests that pass locally may fail when deployed against the actual database engine.

Spring Boot Testcontainers development environment with code editor
Modern Java development environment configured for integration testing

Setting Up Spring Boot Testcontainers in Your Project

Getting started requires adding the Testcontainers dependencies to your Maven or Gradle build. Additionally, Spring Boot 3.1+ provides first-class support through the spring-boot-testcontainers module:

@SpringBootTest
@Testcontainers
class OrderServiceIntegrationTest {

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

    @Autowired
    private OrderRepository orderRepository;

    @Test
    void shouldPersistOrderWithItems() {
        Order order = new Order("customer-1", List.of(
            new OrderItem("SKU-100", 2, 29.99)
        ));
        Order saved = orderRepository.save(order);
        assertThat(saved.getId()).isNotNull();
        assertThat(saved.getItems()).hasSize(1);
    }
}

The @ServiceConnection annotation automatically configures the datasource URL, username, and password. Therefore, you no longer need manual property overrides in your test configuration.

Testing with Multiple Containers

Real applications depend on more than just a database. Specifically, you might need Redis for caching, Kafka for messaging, or Elasticsearch for search. Testcontainers supports all of these simultaneously.

However, running multiple containers increases test startup time. In contrast, using @Container with static fields ensures containers are shared across all test methods in the class. As a result, the overhead is paid only once per test class.

Server-side testing infrastructure with Docker containers
Docker containers providing isolated test environments for each service

Performance Optimization Strategies

Slow integration tests discourage developers from running them frequently. Therefore, consider using Testcontainers reuse mode, which keeps containers alive between test runs. Additionally, parallel test execution with container sharing reduces overall suite duration.

For example, enabling reuse is as simple as adding .withReuse(true) to your container definition. Meanwhile, singleton containers via abstract base classes prevent duplicate container instances across test classes.

CI/CD Pipeline Configuration

Running Testcontainers in CI requires Docker-in-Docker or a mounted Docker socket. Furthermore, GitHub Actions and GitLab CI both support this out of the box with their standard runners. Specifically, configure resource limits to prevent container sprawl in shared CI environments.

CI/CD pipeline running automated integration tests
Automated pipeline executing containerized integration tests

Related Reading:

Further Resources:

In conclusion, Spring Boot Testcontainers enables reliable integration testing by running real dependencies in disposable Docker containers. Therefore, adopt this approach to catch integration bugs early and ship with greater confidence.

Scroll to Top