ユニットテストと結合テスト
公開日: 2025/06/03
ユニットテストと結合テスト:違いを理解して正しく使い分けよう
はじめに
テストコードを書いてはいるけれど、「これはユニットテスト?結合テスト?」「どこまで書けばいい?」と迷うことはありませんか?
ソフトウェア開発において、**ユニットテスト(単体テスト)と結合テスト(インテグレーションテスト)**は目的も対象も異なります。
本記事ではその違いと役割、使い分けのポイントを明確に解説します。
基本情報・概要
-
ユニットテスト(単体テスト)
→ 関数・メソッドなどの「最小単位のロジック」をテスト。高速かつ局所的。 -
結合テスト(インテグレーションテスト)
→ 複数のモジュールやサービスを組み合わせた状態での連携をテスト。
どちらも品質を担保するために不可欠であり、レイヤーごとに適切に設計することでバグの早期発見と修正コスト削減に繋がります。
比較・分類・特徴の表形式まとめ
項目 | ユニットテスト | 結合テスト |
---|---|---|
テスト対象 | 個別の関数・クラス | 複数の関数やモジュールの連携 |
実行速度 | 非常に速い | やや遅い(DB/APIなどに依存する場合あり) |
モックの使用 | 多用される(依存を切るため) | 少なめ/部分的に使う |
目的 | ロジックの正しさ | 連携動作やデータフローの正しさを確認 |
実装コスト | 低(小さくて書きやすい) | 中〜高(セットアップが複雑になりやすい) |
深掘り解説
-
ユニットテストの例(JavaScript):
function sum(a, b) { return a + b; }
test("adds 1 + 2 to equal 3", () => { expect(sum(1, 2)).toBe(3); });
-
結合テストの例(Express × MongoDB):
test("GET /users returns user list", async () => { const response = await request(app).get("/users"); expect(response.statusCode).toBe(200); expect(response.body).toHaveLength(2); });
// ※ テスト前にDBにダミーデータをinsertしておく必要あり
結合テストでは、Expressアプリ・DB・外部APIなど複数の要素が実際に連携することで、実運用に近い形での動作確認が可能です。
応用・発展的な使い方
-
ユニットテスト:
- TDD(テスト駆動開発)との併用で仕様の明確化
- CIに組み込んで高速なデグレチェック
-
結合テスト:
- REST APIのテスト(supertest, jest, pytestなど)
- モックDB(In-Memory)やDocker Composeを使った実環境に近いテスト
-
テストピラミッドの考え方:
E2Eテスト(少) 結合テスト(中) ユニットテスト(多)
→ テストの数と種類のバランスを保つことが重要。
よくある誤解と注意点
- 「ユニットテストだけで十分」:連携による不具合はユニットテストでは検出できない
- 「結合テストは全部自動でやればいい」:設定や実行に時間がかかるため、スコープを絞って書くべき
- ユニットテストが無いまま結合テストだけ書くと、バグの原因箇所が特定しづらくなる
まとめ
ユニットテストと結合テストは「局所の正しさ」と「全体の正しさ」をそれぞれ担保するものであり、両方を使い分けることでソフトウェアの信頼性が大きく向上します。
小さく速く確認できるユニットテストを積み重ねつつ、要所に結合テストを差し込むことで、無駄なく効果的なテスト戦略を築いていきましょう。