mcpField
D
docker-testcontainers

docker-testcontainers

github.com/full-stack-skills测试与质量3108 次安装4 周前更新
代码仓库

关于 docker-testcontainers

面向自动化集成测试的 Testcontainers 指导技能,展示如何在测试中运行数据库和中间件容器,并涵盖容器生命周期与 CI 配置。

主要功能

  1. 01提供 Java 和 Python 示例
  2. 02涵盖 PostgreSQL、Redis 和 Kafka 容器
  3. 03说明共享与按测试创建容器
  4. 04介绍 CI/CD 配置
  5. 05讲解端口映射与资源清理

适用场景

  1. 01为 Java 或 Python 集成测试启动数据库
  2. 02测试依赖 Redis 或 Kafka 的应用
  3. 03在 Spring Boot 测试中注入容器配置
  4. 04在 CI 流程中运行容器化测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/full-stack-skills/docker-skills --skill docker-testcontainers

安装后在 Claude Code 中输入/docker-testcontainers确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
examples/
01-java-postgres.md
02-spring-boot-multi.md
references/
01-container-lifecycle.md
02-patterns-best-practices.md

详细介绍

Docker Testcontainers — 集成测试容器

使用 Testcontainers 在自动化测试中运行 Docker 容器的指南。

适用场景

用户提到以下内容时,始终使用此技能:

  • "testcontainers", "Testcontainer", "测试容器"
  • "集成测试", "docker 测试"
  • "数据库测试", "PostgreSQL test", "MySQL test"
  • "Java Testcontainers", "Python Testcontainers"
  • "测试环境搭建"

Java — Testcontainers

PostgreSQL 示例
@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 示例
@Container
static GenericContainer<?> redis = new GenericContainer<>("redis:7-alpine")
        .withExposedPorts(6379);

// Get connection string
String redisUrl = "redis://" + redis.getHost() + ":" + redis.getMappedPort(6379);
Kafka 示例
@Container
static KafkaContainer kafka = new KafkaContainer(
        DockerImageName.parse("confluentinc/cp-kafka:7.6.0"));

String bootstrapServers = kafka.getBootstrapServers();

Python — testcontainers-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

容器生命周期

// 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 配置

# 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

工作流 — 推荐集成流程

步骤 1:添加依赖:testImplementation 'org.testcontainers:testcontainers:1.20.6' 步骤 2:定义容器:@Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine") 步骤 3:注入配置:使用 @DynamicPropertySource 将容器连接信息注入 Spring 配置 步骤 4:编写测试:编写 @Test void shouldSaveAndFind() 业务测试 步骤 5:加速 CI:启用 withReuse(true) + GHA cache

注意事项 — 常见问题

  • CI 启动缓慢:CI 中需要拉取容器镜像。→ 解决方法:在测试步骤之前添加 docker pull postgres:16-alpine 进行预热;在 .testcontainers.properties 中启用 withReuse(true)。
  • CI 中的端口冲突:Testcontainers 会选择随机端口,因此不会冲突。但测试中硬编码的端口会导致失败。→ 解决方法:始终使用 container.getMappedPort(5432),不要硬编码端口号。
  • 资源清理:Ryuk 会自动移除容器。在 CI 中,请确保配置了 DinD 或可访问 Docker socket。→ 解决方法:如果设置了 TESTCONTAINERS_RYUK_DISABLED=true,请添加 @AfterAll 清理;检查 CI 中是否挂载了 Docker socket。
  • 静态容器与实例容器:静态 @Container 字段会在整个类中共享一个容器。实例字段则会为每项测试创建容器。→ 解决方法:数据库使用静态容器(可共享状态);对隔离要求严格的测试使用实例容器;对于 JUnit 5,请检查 @TestInstance(TestInstance.Lifecycle.PER_CLASS)。

边界 — 能力边界(适用与不适用场景)

分类场景说明
✅ 能做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)

不适用此技能的场景

❌ 跳过✅ 改用
手动测试docker-run
生产数据库测试docker-storage + 实际实例
模拟测试使用 Mockito/unittest.mock
Docker 基础知识docker-basics

安全与稳定性

  • Testcontainers 使用随机端口,不会与运行中的服务发生端口冲突。
  • 测试完成后,Ryuk 会自动清理容器。
  • 切勿在生产代码中使用 Testcontainers;仅用于测试。
  • 在本地开发中使用 withReuse(true) 可加快测试速度(容器会在多次运行之间保留)。

📚 官方文档参考

文档地址
Testcontainers 概述https://docs.docker.com/testcontainers/
Testcontainers for Javahttps://java.testcontainers.org/
Testcontainers Cloudhttps://testcontainers.com/cloud/
Spring Boot 集成https://java.testcontainers.org/modules/spring-boot/
CI 配置https://java.testcontainers.org/supported_docker_environment/continuous_integration/

🧭 Docker 技能路线

📍 你在这里:docker-testcontainers — 测试容器

← 上一步:docker-troubleshooting — 问题排查 → 下一步:docker-ai-ml — AI/ML 工作负载

常见问题

Q1:如何快速上手此技能? A:参考上方的快速开始章节,按步骤操作即可。

Q2:遇到版本不兼容问题怎么办? A:检查依赖版本,使用 lock 文件锁定,参考常见问题章节。

Q3:如何在生产环境中使用? A:参考最佳实践章节,确保配置正确,并做好监控和日志记录。

Q4:如何优化性能? A:参考性能优化相关文档,使用缓存、索引等手段。

Q5:如何贡献或反馈问题? A:在 GitHub 仓库提交 Issue 或 Pull Request。

Q6:是否支持中文? A:支持中文文档和中文注释,详见国内适配章节。

评论

支持 Markdown