Java

223 posts in this section

Container Reuse for Fast Feedback Loops

The singleton pattern shares a container within a single test run. Container reuse goes further — it keeps the container alive after the JVM exits and reuses it in the next test run. The first run pays the startup cost (8 seconds for Kafka). Every subsequent run skips it entirely. For a developer who runs the test suite dozens of times per day, this saves minutes of waiting. What You’ll Learn Enabling container reuse with .

Continue reading »

Database Migration Testing — Flyway and Liquibase with Testcontainers

Database migrations are the most dangerous code in most applications. A failed migration in production means downtime. A migration that succeeds but corrupts data is worse. Testing migrations against the actual target database — not H2, not a manual inspection — is the only way to catch migration bugs before they reach production. This article covers testing Flyway and Liquibase migrations with Testcontainers, verifying schema correctness after migration, and testing rollback scenarios.

Continue reading »

JUnit 5 Integration — Lifecycle and Annotations

The biggest performance factor in a Testcontainers test suite is how many times you start and stop containers. Start a PostgreSQL container once per JVM and your tests add 2 seconds to total CI time. Start it once per test method and 50 tests cost 100 seconds. Understanding Testcontainers lifecycle management is how you write fast tests without sacrificing isolation. This article covers all the container lifecycle options in JUnit 5 — from the simplest @Container annotation to the singleton pattern that shares one container across your entire test suite.

Continue reading »

Kafka Integration Testing with Testcontainers

@EmbeddedKafka has long been the standard for Kafka testing in Spring Boot. It works, but it runs a different Kafka implementation than production — one that can accept messages and serialize records in ways that a real Kafka broker would not. KafkaContainer runs the same Confluent Kafka image your production environment uses, with the same broker configuration, same partition behavior, and same consumer group offset management. This article shows how to test Kafka producers, consumers, and dead-letter topics with a real broker.

Continue reading »

Keycloak and OAuth2 Testing with Testcontainers

Testing Spring Security with @WithMockUser and SecurityMockMvcRequestPostProcessors.jwt() verifies that your authorization annotations are wired correctly, but it does not test JWT validation, token signing algorithms, issuer URL verification, or clock skew handling. These require a real OAuth2 provider. KeycloakContainer runs a real Keycloak instance in Docker, giving you a complete OIDC server for integration tests. What You’ll Learn KeycloakContainer setup from the community module Importing a Keycloak realm for tests Retrieving JWT access tokens programmatically Testing protected endpoints with real JWTs Testing role-based access control (RBAC) Testing token expiry and refresh flows Dependencies KeycloakContainer is not in the Testcontainers core library.

Continue reading »

LocalStack — Testing AWS Services (S3, SQS, SNS) with Testcontainers

Testing AWS integrations against real AWS services requires IAM credentials, costs money per test run, and creates real side effects (files in S3, messages in SQS). LocalStack runs a local AWS cloud emulator in Docker — the same API, the same response format, but running locally with no AWS account required. This article covers testing S3, SQS, and SNS integrations with LocalStackContainer. What You’ll Learn LocalStackContainer setup and @ServiceConnection Creating S3 buckets and testing file upload/download Testing SQS message producers and @SqsListener consumers Testing SNS to SQS subscriptions Creating AWS resources before tests with the AWS SDK Testing DynamoDB operations Dependencies <dependency> <groupId>io.

Continue reading »

MongoDB and NoSQL Testing with Testcontainers

MongoDB’s document model introduces testing challenges that relational database tests do not have: schema flexibility (different documents can have different fields), aggregation pipelines, geospatial queries, and text search. Testing these against an embedded Flapdoodle MongoDB works for basic CRUD but breaks down for aggregation pipelines, custom index types, and MongoDB-version-specific behavior. This article covers MongoDB testing with a real MongoDB container. What You’ll Learn MongoDBContainer setup and @ServiceConnection @DataMongoTest slice testing for repositories Testing aggregation pipelines Testing compound indexes and text indexes Querying documents with MongoTemplate Testing document validation rules Dependencies <dependency> <groupId>org.

Continue reading »

MySQL Testing with Testcontainers

MySQL is still the most widely deployed relational database in Java applications. Its SQL dialect, strict mode behavior, and character set handling differ from both H2 and PostgreSQL in ways that matter for real applications. This article covers MySQL testing with Testcontainers — from basic setup to MySQL-specific features and the STRICT_TRANS_TABLES mode that catches data truncation bugs H2 silently ignores. What You’ll Learn MySQLContainer setup and configuration @ServiceConnection with MySQL MySQL strict mode and why it matters for tests Character set and collation configuration Testing MySQL-specific SQL functions MariaDB as an alternative Dependencies <dependency> <groupId>org.

Continue reading »

Parallel Test Execution with Testcontainers

A test suite with 50 integration test classes runs sequentially in 10 minutes. Configured for parallel execution across 4 threads, it completes in 3 minutes. Parallel test execution with Testcontainers requires careful data isolation — tests running simultaneously against the same database will step on each other’s data without it. This article covers JUnit 5 parallel configuration, container sharing strategies, and data isolation techniques. What You’ll Learn JUnit 5 parallel execution configuration with junit-platform.

Continue reading »

PostgreSQL Testing with Testcontainers

Testing database code against H2 gives you a false sense of security. PostgreSQL has different behavior for ON CONFLICT, RETURNING, JSON operators, full-text search, and dozens of other features. A JPA query that works in H2 dialect may fail against real PostgreSQL. This article shows how to test your Spring Data JPA repositories, custom queries, and database constraints against a real PostgreSQL instance using Testcontainers. What You’ll Learn @ServiceConnection — the Spring Boot 3.

Continue reading »