CI における service container とは?テスト用のデータベース
service container とは、統合テストが本物の対話相手を持てるよう、CI プロバイダがあなたの job の隣に起動する補助的なコンテナ - データベース、cache、キュー - のことです。
多くのテストは、生きた依存関係を必要とします。Postgres データベース、Redis cache、message broker などです。これらを runner にインストールして管理する代わりに、CI システムでは service container を宣言できます。プロバイダがそれらを job と並べて起動し、ネットワーキングを配線し、後で片付けます。
解決する問題
統合テストは、mock ではなく本物のデータベースエンジンに対して実行されるときにはるかに価値があります。service container はそれを安価で再現可能にします - 実行のたびにクリーンな Postgres が用意され、host を汚しません。
job からの到達方法
サービスは hostname(多くの場合そのサービスの label)によってネットワーク経由で到達できます。テスト設定はその host とマッピングされた port を指し、他のどのデータベースと同じように接続します。
GitHub Actions の例
workflow では、postgres イメージ、パスワード用の env、port マッピングを持つ services: ブロックを追加します。runner は step の前にそれを起動し、テストはサービスの hostname 経由でそれに接続します。
readiness が重要
- データベースは、初期化を終えてからでないと接続を受け付けないことがあります。
- health check や wait ループが「connection refused」の flake を防ぎます。
- テストが既知の状態から始まるよう、init step で seed データを投入します。
service container と信頼性
サービスイメージの pull と起動は時間を要し、たまに一時的な障害を伴います。マネージド runner は一般的なサービスイメージを cache し、registry の一時的な失敗を自動 retry するため、遅い、あるいは不安定な pull が、本来 green だったはずのテスト実行を失敗させることはありません。
重要なポイント
- service container は、テスト用に CI が管理する依存関係(DB、cache、キュー)です。
- job は hostname と port を通じてネットワーク経由で到達します。
- connection-refused の flakiness を避けるため、readiness を待ちましょう。