docker-testcontainers
Guidance for Testcontainers — running Docker containers in automated integration tests. Covers Java (@Testcontainers, @Container, PostgreSQL/Redis/Kafka/Elasticsearch), Python (testcontainers-python with pytest), container lifecycle management (singleton, reuse), CI/CD integration (Docker-in-Docker, Ryuk), Testcontainer best practices, and database migration testing. Use when the user asks about testcontainers, integration testing with Docker, database testing, Java testcontainers, Python testcontainers, or needs to test with real Docker services. 使用场景:testcontainers、集成测试、docker 测试、数据库测试、Java Testcontainers、Python Testcontainers.
Works with
---
name: docker-testcontainers
description: Guidance for Testcontainers — running Docker containers in automated integration tests. Covers Java (@Testcontainers, @Container, PostgreSQL/Redis/Kafka/Elasticsearch), Python (testcontainers-python with pytest), container lifecycle management (singleton, reuse), CI/CD integration (Docker-in-Docker, Ryuk), Testcontainer best practices, and database migration testing. Use when the user asks about testcontainers, integration testing with Docker, database testing, Java testcontainers, Python testcontainers, or needs to test with real Docker services. 使用场景:testcontainers、集成测试、docker 测试、数据库测试、Java Testcontainers、Python Testcontainers.
license: Apache-2.0
---
# Docker Testcontainers — 集成测试容器
Guidance for running Docker containers in automated tests with Testcontainers.
## When to Use
**ALWAYS use this skill when the user mentions:**
- "testcontainers", "Testcontainer", "测试容器"
- "集成测试", "docker 测试"
- "数据库测试", "PostgreSQL test", "MySQL test"
- "Java Testcontainers", "Python Testcontainers"
- "测试环境搭建"
## Java — Testcontainers
### PostgreSQL Example
```java
@Testcontainers
@SpringBootTest
class OrderRepositoryTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
@DynamicPropertySource
static void configure(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Test
void shouldSaveAndFindOrder() {
Order saved = repository.save(new Order(...));
assertThat(repository.findById(saved.getId())).isPresent();
}
}
```
### Redis Example
```java
@Container
static GenericContainer<?> redis = new GenericContainer<>("redis:7-alpine")
.withExposedPorts(6379);
// Get connection string
String redisUrl = "redis://" + redis.getHost() + ":" + redis.getMappedPort(6379);
```
### Kafka Example
```java
@Container
static KafkaContainer kafka = new KafkaContainer(
DockerImageName.parse("confluentinc/cp-kafka:7.6.0"));
String bootstrapServers = kafka.getBootstrapServers();
```
## Python — testcontainers-python
```python
import pytest
from testcontainers.postgres import PostgresContainer
from testcontainers.redis import RedisContainer
@pytest.fixture(scope="module")
def postgres():
with PostgresContainer("postgres:16-alpine") as pg:
yield pg.get_connection_url()
def test_database_connection(postgres):
import psycopg2
conn = psycopg2.connect(postgres)
assert conn.status == psycopg2.STATUS_READY
```
## Container Lifecycle
```java
// Singleton: one container for all tests
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");
// Per-test: new container for each test
@Test
void test() {
try (var redis = new GenericContainer<>("redis:7")) {
redis.start();
// test...
} // auto-closed by try-with-resources
}
```
## CI/CD Configuration
```yaml
# GitHub Actions — DinD (Docker-in-Docker)
jobs:
test:
runs-on: ubuntu-latest
services:
docker:
image: docker:27-dind
options: --privileged
steps:
- uses: actions/checkout@v4
- run: ./gradlew test
```
## Workflow — 推荐集成流程
Step 1: **添加依赖**: `testImplementation 'org.testcontainers:testcontainers:1.20.6'`
Step 2: **定义容器**: `@Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")`
Step 3: **注入配置**: `@DynamicPropertySource` 将容器连接信息注入 Spring 配置
Step 4: **编写测试**: `@Test void shouldSaveAndFind()` 正常业务测试
Step 5: **CI 加速**: 启用 `withReuse(true)` + GHA cache
## Gotchas — Common Pitfalls
- **CI slow startup**: Container images need to be pulled in CI. → **Recovery**: Pre-warm by adding `docker pull postgres:16-alpine` before test step; enable `withReuse(true)` in `.testcontainers.properties`.
- **Port conflicts in CI**: Testcontainers picks random ports — no conflicts. But hardcoded ports in tests will fail. → **Recovery**: Always use `container.getMappedPort(5432)` instead of hardcoding port numbers.
- **Resource cleanup**: Ryuk auto-removes containers. In CI, ensure DinD or socket access. → **Recovery**: If `TESTCONTAINERS_RYUK_DISABLED=true`, add `@AfterAll` cleanup; check Docker socket is mounted in CI.
- **Static vs instance containers**: Static `@Container` fields share ONE container across the class. Instance fields create per-test containers. → **Recovery**: Use static for databases (shared state OK); use instance for isolation-critical tests; check `@TestInstance(TestInstance.Lifecycle.PER_CLASS)` for JUnit 5.
## Boundary — 能力边界(适用与不适用场景)
| 分类 | 场景 | 说明 |
|------|------|------|
| ✅ 能做 | Java/Python 集成测试 | PostgreSQL/MySQL/Redis/Kafka 等容器化数据库测试 |
| ✅ 能做 | Spring Boot 测试 | @Testcontainers + @DynamicPropertySource 自动注入 |
| ✅ 能做 | CI 集成 | GitHub Actions/Jenkins 中自动启动/清理 |
| ⚠️ 需条件 | 跨 JVM 复用 | 需配置 `testcontainers.reuse.enable=true` |
| ⚠️ 需条件 | 非 Java 语言测试 | 使用各语言对应 Testcontainers 库 |
| ❌ 超范围 | 手动测试/调试 | 使用 `docker-run` |
| ❌ 超范围 | 生产数据库测试 | 连接生产实例而非容器 |
| ❌ 超范围 | 性能/压测 | 专用工具(JMeter/K6) |
## When NOT to Use This Skill
| ❌ Skip | ✅ Use Instead |
|---------|---------------|
| Manual testing | `docker-run` |
| Production database testing | `docker-storage` + real instance |
| Mock testing | Use Mockito/unittest.mock |
| Docker basics | `docker-basics` |
## Security & Stability
- Testcontainers use random ports — no port conflicts with running services.
- Containers are automatically cleaned up by Ryuk after test completion.
- Never use Testcontainers in production code — test scope only.
- Use `withReuse(true)` for local development to speed up tests (container survives between runs).
## 📚 官方文档参考
| 文档 | 地址 |
|------|------|
| Testcontainers 概述 | https://docs.docker.com/testcontainers/ |
| Testcontainers for Java | https://java.testcontainers.org/ |
| Testcontainers Cloud | https://testcontainers.com/cloud/ |
| Spring Boot 集成 | https://java.testcontainers.org/modules/spring-boot/ |
| CI 配置 | https://java.testcontainers.org/supported_docker_environment/continuous_integration/ |
## 🧭 Docker Skills Journey
> 📍 **You are here: `docker-testcontainers` — 测试容器**
**← Prev**: `docker-troubleshooting` — Problem debugging
**→ Next**: `docker-ai-ml` — AI/ML workloads
## FAQ
**Q1: 如何快速上手此技能?**
A: 参考上方的快速开始章节,按步骤操作即可。
**Q2: 遇到版本不兼容问题怎么办?**
A: 检查依赖版本,使用 lock 文件锁定,参考常见陷阱章节。
**Q3: 如何在生产环境使用?**
A: 参考最佳实践章节,确保配置正确,做好监控和日志。
**Q4: 性能如何优化?**
A: 参考性能优化相关文档,使用缓存、索引等手段。
**Q5: 如何贡献或反馈问题?**
A: 在 GitHub 仓库提交 Issue 或 Pull Request。
**Q6: 是否支持中文?**
A: 支持中文文档和中文注释,详见国内适配章节。More Testing skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
setup-pre-commit
mattpocock/skills
Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo. Use when user wants to add pre-commit hooks, set up Husky, configure lint-staged, or add commit-time formatting/typechecking/testing.
agent-browser
vercel-labs/agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.

