用語集 · テストの基礎
結合テスト(インテグレーションテスト)
英語: Integration test
別名: 結合テスト, 統合テスト, インテグレーションテスト, integration tests
定義
サービスとデータベース、2 つの API など、2 つ以上のコンポーネントが実際のインターフェースを通じて正しく連携するかを確認するテストです。
結合テストは、1 つのコンポーネント内部のロジックではなく、コンポーネント間のつながりを検証します。少なくとも 1 つの境界で本物の実装を使います。実際のデータベースに対するリポジトリ、別のサービスの API を呼び出すサービス、メッセージのプロデューサーとそのコンシューマーなどです。誤った SQL、不正なシリアライズ、設定の欠落、契約の不一致を捉えるのがこのテストで、これらはモックを使ったユニットテストではすべて見逃されます。
具体例
OrderRepository はモックを使ってユニットテストされており、それらのテストは合格しています。結合テストでは、コンテナで起動した実際の PostgreSQL インスタンスに対してこれを実行します。
- Testcontainers で PostgreSQL を起動し、スキーマのマイグレーションを適用します。
- リポジトリ経由で、明細行が 3 つある注文を保存します。
- ID で読み込み直し、合計と明細行が一致することをアサートします。
- 日付範囲で注文を検索し、境界が両端を含むことをアサートします。
実際のデータベースに対して実行すると、このテストはカラム名の誤字、適用されていなかったマイグレーション、タイムゾーン変換の誤り、インメモリデータベースでは動くが PostgreSQL では動かないクエリなどを明らかにできます。
結合テスト・単体テスト・E2E テストの比較
| 単体(ユニット) | 結合 | E2E | |
|---|---|---|---|
| 範囲 | 1 つの関数またはクラス | いくつかのコンポーネントとそのインターフェース | ユーザーから見たシステム全体 |
| 依存先 | テストダブルに置き換え | テスト対象の境界では本物 | すべて本物 |
| 速度 | ミリ秒 | 秒 | 秒〜分 |
| 失敗が示す場所 | 特定のロジック | 特定のインターフェース | システムのどこか |
アプローチ
- 狭い結合テストは、1 度に 1 つの境界(サービスとデータベースなど)を確認し、それ以外はすべてスタブにします。高速で的確なため、多くのチームはこれを数多く用意したいと考えます。
- 広い結合テストは、複数の実際のサービスを一緒に起動します。信頼性は高まりますが、遅く、原因の特定も難しくなります。
- 古典的な教科書では、モジュールを組み合わせる順序としてビッグバン、トップダウン、ボトムアップの結合も説明されています。面接では用語を知っておくと役立ちますが、現代のチームはほとんどが継続的に結合しています。
よくある間違い
- 長期間使い続ける 1 つのデータベースをテストと開発者で共有し、結果が残存データに左右されるようにしてしまう。実行ごとにクリーンで使い捨てのインスタンスを用意します。
- テストしたかった境界そのものをモックにしてしまい、結合テストをユニットテストに戻してしまう。