[Testcontainers] Docker コンテナ間テストの自動化手法

はじめに
こんにちは、ソリューション事業部の斉藤です。
最近は自社プロダクト開発に携わるようになりました。
日々、品質を高めたい、継続的に品質を守りながらプロダク トを更新したい、と開発しています。
その中で「プロダクトのDockerコンテナ間テストができないだろうか」と考え始めました。
コンテナ間のテストがしたい
プロダクトのコンテナとはいわゆるマイクロサービス一つ一つのことを指していまして、次のようなものが挙げられます。
- フロントエンドコンテナ
- バックエンドコンテナ
- DBコンテナ
- バッチコンテナ
今までは、それぞれのコンテナ内でユニットテストが書けているものの、コンテナを繋ぎ合わせた時の動きは手動で確認していました。
これを自動化したい、というモチベーションがあります。
例えば次のようなシナリオです。
- バッチコンテナが外部APIを実行し、データを取得する
- 1で取得したデータを、バッチコンテナがバックエンドコンテナの登録APIに送信する
- 2で入ってきたデータを、バックエンドコンテナがDBコンテナに入れる
(バッチコンテナがDBに直接登録、という話もあろうかとは思いますが、プロダクトの性質上このシナリオとなりました。)
要は「バッチが取得したデータは、それぞれのコンテナを経由してDBに意図通りに入ったか?」をテストしたい、ということですね。
そこで採用したのが、Testcontainersという技術です。
Testcontainers
Docker を使って一時的なコンテナを立ち上げることができるツールです。
特に「一時的」というのがコア技術だそうで、Ryukというクリーンアップ用コンテナによって、使い終わったコンテナ、ボリューム、ネットワーク、イメージを削除する機能が入っています。
(Ryukという名前は、漫画デスノートに出てくる死神リュークに因んでいるそうです)
この技術を使ってテストを書くことにしました。
使用した環境は以下の通りです。
- Testcontainers@10.28.0
- Vitest@2.1.9
- シナリオとテストコードを実行する環境として利用
- pg@8.20.0
- プロダクトのバッチコンテナイメージ
- プロダクトのバックエンドコンテナイメージ
- プロダクトのDBコンテナイメージ
以下、サンプルとして検証した内容を示します。
検証した内容
コンテナ内のDockerfileやアプリソースコードを全て示すのは冗長になるため、以下のみ記載します。
- シーケンス図
- テストしたいシナリオ含む、全体の流れを表現
- コンテナのインターフェイス
- コンテナのリクエスト、レスポンスを表現
- compose.test.yaml
- docker compose コマンドで立ち上げたい、コンテナの内容
- batch.integration.test.ts
- テストしたいシナリオ含む、全体の流れをTestcontainersを使った記載
シーケンス図

コンテナのインターフェイス
上記シーケンス図内の番号に対応する、コンテナのインターフェイスを示します。
4, 5 外部APIからユーザー一覧を取得する
GET /users
Response:
[
{
"email": "yamada@example.com",
"displayName": "