docker-testcontainers について
自動化された統合テスト向けのTestcontainersガイダンススキルです。テストでデータベースやミドルウェアのコンテナを実行する方法に加え、ライフサイクルとCI設定を説明します。
主な機能
- 01JavaとPythonのサンプル
- 02PostgreSQL、Redis、Kafkaコンテナへの対応
- 03共有コンテナとテストごとの起動方法
- 04CI/CD設定の解説
- 05マッピングポートとクリーンアップの説明
活用シーン
- 01JavaやPythonの統合テストでデータベースを起動する場面
- 02RedisやKafkaに依存するアプリをテストする場面
- 03Spring Bootテストにコンテナ設定を注入する場面
- 04CIでコンテナベースのテストを実行する場面
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ full-stack-skills/ docker-skills --skill docker-testcontainersインストール後、Claude Code で/docker-testcontainersを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlexamples/01-java-postgres.md02-spring-boot-multi.mdreferences/01-container-lifecycle.md02-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
ワークフロー — 推奨する統合手順
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 キャッシュを有効にします
注意点 — よくある落とし穴
- CI の起動が遅い: CI ではコンテナイメージをプルする必要があります。→ 対処法: テスト手順の前に
docker pull postgres:16-alpineを追加して事前に取得し、.testcontainers.propertiesでwithReuse(true)を有効にします。 - CI でのポート競合: Testcontainers はランダムなポートを選ぶため、競合しません。ただし、テストでポートをハードコードすると失敗します。→ 対処法: ポート番号をハードコードせず、必ず
container.getMappedPort(5432)を使用します。 - リソースのクリーンアップ: Ryuk がコンテナを自動的に削除します。CI では DinD またはソケットへのアクセスが必要です。→ 対処法:
TESTCONTAINERS_RYUK_DISABLED=trueの場合は、@AfterAllによるクリーンアップを追加し、CI で Docker ソケットがマウントされていることを確認します。 - static コンテナとインスタンスコンテナ: static な
@Containerフィールドは、クラス内で 1 つのコンテナを共有します。インスタンスフィールドでは、テストごとにコンテナが作成されます。→ 対処法: データベースには static を使用します(状態の共有が問題ない場合)。分離が重要なテストではインスタンスフィールドを使用し、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)を使用します(実行間でコンテナが維持されます)。
📚 公式ドキュメント
| ドキュメント | URL |
|---|---|
| Testcontainers の概要 | https://docs.docker.com/testcontainers/ |
| Java 向け Testcontainers | 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 スキルの進め方
📍 現在の位置:
docker-testcontainers— テストコンテナ
← 前へ: docker-troubleshooting — 問題のデバッグ
→ 次へ: docker-ai-ml — AI/ML ワークロード
FAQ
Q1: このスキルをすぐに使い始めるにはどうすればよいですか? A: 上記のクイックスタートのセクションを参照し、手順に沿って操作してください。
Q2: バージョンの互換性に問題がある場合はどうすればよいですか? A: 依存関係のバージョンを確認し、lock ファイルで固定してください。よくある落とし穴のセクションも参照してください。
Q3: 本番環境で使用するにはどうすればよいですか? A: ベストプラクティスのセクションを参照し、設定が正しいことを確認したうえで、監視とログを整備してください。
Q4: パフォーマンスを最適化するにはどうすればよいですか? A: パフォーマンス最適化に関するドキュメントを参照し、キャッシュやインデックスなどを活用してください。
Q5: 貢献したり、問題を報告したりするにはどうすればよいですか? A: GitHub リポジトリで Issue または Pull Request を作成してください。
Q6: 中国語に対応していますか? A: 中国語のドキュメントとコメントに対応しています。国内向け対応のセクションを参照してください。