Table of Contents
What Is Testcontainers? - A Practical Guide to "Real" Testing Environments
Today, we'll thoroughly explain Testcontainers, a tool that might feel a bit unfamiliar at first. I'll explain it in a lecture style, covering its history, background, specific examples, and pros and cons so that even beginners can get a clear picture.
1. Introduction: Testcontainers Is a Tool, Not a Concept
First, the most important thing to understand is that Testcontainers is not just a concept name, but a collection of OSS libraries. It's a Docker-based testing support tool created to solve the common problem: "I want to bring up real databases or message queues only during testing."
The Java implementation is particularly famous and works with JUnit using annotations like the following.
First, use the "@Testcontainers" annotation to declare that this test class manages containers. Then, use the "@Container" annotation to specify the container you want to start (e.g., PostgreSQL).
In other words, it operates as a JUnit extension library, not as an internal JUnit feature. This is clearly stated in the official documentation and explanations for each language version.
💡 Point: While Testcontainers' Java version is famous, official implementations also exist for Node.js, Python, and .NET. Choose the one that matches your language.
2. Historical Background: Why Testcontainers Was Born
2-1. Problems with Traditional Testing
Everyone, have you experienced any of these?
- Mocks worked fine in tests but failed in production
- Multiple people used a shared test database simultaneously, contaminating data
- CI environment and developer local environment behaved differently
Traditional methods each have their advantages, but they had issues with "reproducibility" and "reliability".
2-2. Docker's Game-Changing Impact
Then Docker appeared. By spinning up lightweight, fast containers only during test execution and deleting them afterward, we could achieve:
- "Same environment every time"
- "Not affected by others' test results"
- "Can use real dependency services"
Testcontainers is the concrete implementation of this idea.
🔄 Improved Reproducibility: By pinning Docker image tags, you can minimize situations like "it worked last week but not this week."
3. Basic Structure and Mechanism of Testcontainers
3-1. Library Characteristics
- Docker Dependent: Internally operates Docker to start containers
- Disposable (ephemeral): Starts at test beginning, deletes at test end
- Multi-language Implementation: Available for Java, .NET, Node.js, Python, and more
- Reuse Options: Basic is to rebuild for each test, but reuse settings are available for speed
3-2. JUnit Integration Example
@Testcontainers
class MyDatabaseTest {
@Container
static PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:16-alpine");
@Test
void testInsertAndQuery() {
DataSource ds = getDataSource(postgres);
runMigrations(ds);
assertEquals(42, queryCount(ds));
}
}
@Testcontainersdeclares "this class uses containers"@Containerspecifies "start Postgres"- Automatically waits during tests and destroys after test completion
The important point here is that this functionality is not built into JUnit itself, but Testcontainers operates as an external library that extends JUnit.
4. Compatibility with Golden Master: Automating Before/After Comparisons
Here, let me introduce the concept of "Golden Master." This is a testing method that saves existing operation results as a "golden standard" and compares them with new version processing results.
For example, run batch on old infrastructure and save output (Before), process same input on new infrastructure and compare results (After). By automatically checking this difference, we can improve migration safety.
With Testcontainers, you can script:
- Start old DB container for Before
- Start new DB container for After
- Process with same input data
- Compare outputs or DB snapshots
This makes it very suitable for automating new/old comparison tests.
🧪 Golden Master Check Example
1. Start old version API with Testcontainers
2. Send same HTTP requests to new version
3. Save response body as JSON snapshot
4. Alert to Slack if there are differences
5. Organizing Pros and Cons
5-1. Advantages (Pros)
- Reproducibility: With fixed Docker images, anyone can get the same results anywhere
- Reliability: Can detect bugs that mocks can't catch, unique to real services
- Automation: Can complete startup to deletion in code, easy to integrate into CI/CD
- Independence: Isolated per test, so no data contamination occurs
5-2. Disadvantages (Cons)
- Startup Cost: Takes time to start containers
- Docker Dependency: Requires Docker in development environment and CI
- Version Management: Regular updates needed to avoid differences from production
- Network Restrictions: Requires ingenuity for introduction in closed corporate environments
6. Practical Usage Patterns and Best Practices
- 1 Test = 1 Container: High isolation but takes time. Limit to critical tests
- Shared per Test Class: Fast startup. Key is to define
@Testcontainersas static and do proper initialization - Docker Compose Integration: Start DB + MQ + cache together. Convenient when there are many peripheral services
- CI/CD Integration: Automate with GitHub Actions or GitLab CI. Design cache strategy combined with
services
✅ Operations Tip: In CI, reusing containers per Pull Request saves time. However, script reset procedures to prevent data contamination.
7. Common Pitfalls and How to Avoid Them
- Tests occasionally fail → Insufficient startup waiting. Add health checks or SQL response confirmation
- Slow → Lightweight images and introduce container reuse options
- CI failures → Check permissions and network restrictions, get Docker socket sharing permission
- Can't read differences → Normalize Golden Master outputs to comparable format before comparison
8. Fun Knowledge: Similarity to Frontend
The Golden Master concept is similar to "snapshot testing" in the frontend world. Capture UI states and save them, then detect differences in subsequent runs. Testcontainers can be said to extend this idea to the infrastructure level.
🎮 Similar Concept Example: Storybook's visual regression tests also compare differences with existing screenshots. Testcontainers is a toolkit that brings this concept to the backend.
9. Summary and Next Steps
- Testcontainers is not a concept but an OSS library collection that uses Docker to start real services only during testing
- Combined with Golden Master methods, it can automate new/old comparison verification
- Advantages are reproducibility, reliability, and automation; disadvantages are startup cost and Docker dependency
- Easy to introduce even in small projects, so start with database-dependent integration tests
Please try it once in a small test. By experiencing "tests that use the real thing", your testing design perspective should greatly expand.

NEW NOVEL 2026/08/01
Clouded Glass
Polishing is not about force.
Volume two of The World Became Slightly Farther Away.Five stories that can also be read as a starting point.
View on Amazon
Jijoden.com
Your life is worth writing.
There is a truer self you can tell only to AI.Gather fragments of memory into a single story.
Take a LookRelated Articles
Why the Benchmark King Breaks Code in the Field: The Real Reason Google Antigravity Isn't Catching On
Why does Google Antigravity cause regressions in the field? We explore the overwhelming cost performance of its $20 monthly plan and the mystery of why Google is lagging behind in AI coding agents, separating model intelligence from product quality.
OpenAI Reaches Pentagon Agreement While Anthropic Faces Exclusion? Verification and Implications (As of March 4, 2026)
A source-first analysis of OpenAI's Pentagon agreements, evidence behind the Anthropic exclusion narrative, unresolved legal questions, and policy implications.
What I Learned from Trading FX with LLMs
A detailed log of building an AI-powered automated FX trading system and running it live for a month, revealing what LLMs are bad at and where they actually shine.
Why GPT-5.3-Codex-Spark Feels Fast: A Speed Architecture for Rewiring Developer Loops
This article maps the February 2026 Codex updates and explains what makes GPT-5.3-Codex-Spark feel fast, how to read benchmark claims, and how to combine Spark with GPT-5.3-Codex in real engineering workflows.
Deconstructing Gemini Spark: 24/7 Always-On AI Agent Architecture
The paradigm shift of 'Autonomous Always-On AI' brought by Gemini Spark. We explore the Long-Horizon execution engine orchestrating Google Workspace and provide a direct comparison with Claude Cowork and Anti-Gravity.