7-1. ユニット・統合・E2Eテストの違い
このセクションで学ぶこと
Section titled “このセクションで学ぶこと”- テストをなぜ書くのか
- ユニットテスト・統合テスト・E2Eテストの役割と違い
- それぞれをどんな場面で使い分けるか
- テストピラミッドの考え方
バグを「後で見つける」より「早く見つける」ほうが、修正コストは低い。 テストは、ソフトウェアが意図通りに動くことを機械的に確認する仕組み である。
1. なぜテストを書くのか
Section titled “1. なぜテストを書くのか”コードを書くだけでは、次のような問題が起きやすい。
機能を追加した ↓別の機能が壊れた ↓気づかないまま本番リリース ↓利用者がバグに遭遇テストを書いておくと、この連鎖を早期に止めやすくなる。
機能を追加した ↓テストを実行 ↓別のテストが失敗 ↓修正してからリリーステストが与えてくれるもの
Section titled “テストが与えてくれるもの”| 目的 | 説明 |
|---|---|
| バグの早期発見 | 本番前に問題を見つけやすくなる |
| 変更への安心感 | 既存の動作を壊していないか確認できる |
| 仕様のドキュメント化 | テストコードが「こう動くべき」を示す |
| リファクタリングの支援 | 構造を変えても動作が変わらないことを確認できる |
2. テストの種類
Section titled “2. テストの種類”ソフトウェアテストには代表的な 3 種類がある。
ユニットテスト → 部品単体統合テスト → 部品を組み合わせた動きE2Eテスト → 利用者の視点で全体を通すそれぞれを詳しく見ていく。
3. ユニットテスト
Section titled “3. ユニットテスト”ユニットテストは、関数やクラスといった小さな単位の動作を確認するテスト である。
関数 calcTax(price, rate) ↓入力 1000, 0.1 ↓期待出力 100 ↓実際の出力と比較何をテストするか
Section titled “何をテストするか”- 特定の入力に対して正しい値が返るか
- 境界値(0・負数・最大値など)で正しく動くか
- エラー条件でどう振る舞うか
| 項目 | 内容 |
|---|---|
| 速度 | 速い(データベースや外部通信を使わない) |
| 安定性 | 安定しやすい(外部依存がない) |
| 範囲 | 狭い(1つの関数や小さなクラス) |
| 書きやすさ | 比較的書きやすい |
コード例のイメージ
Section titled “コード例のイメージ”# 対象関数: calcTax(price, rate) → price * rate
# テスト入力 1000, 0.1 → 期待値 100入力 0, 0.1 → 期待値 0入力 1000, 0 → 期待値 0ユニットテストは「設計の最小単位が正しいか」を確認する。
4. 統合テスト
Section titled “4. 統合テスト”統合テストは、複数の部品が組み合わさったときの動作を確認するテスト である。
APIエンドポイント ↓入力バリデーション層 ↓サービス層(ビジネスロジック) ↓データベース層これらをつないだ状態で、正しく連携しているかを確認する。
なぜ統合テストが必要か
Section titled “なぜ統合テストが必要か”ユニットテストが全部通っても、部品の組み合わせ方が間違っているとバグになる。
部品A: 正しく動く部品B: 正しく動く部品AとBの結合: 渡すデータの形式が合わなくて壊れる統合テストは、こうした「接続部分のズレ」を見つけるために使う。
| 項目 | 内容 |
|---|---|
| 速度 | ユニットテストより遅い(DBや外部サービスを使うことがある) |
| 安定性 | 外部依存があると不安定になりやすい |
| 範囲 | 中程度(複数コンポーネントの連携) |
| 書きやすさ | ユニットテストより難しい場合が多い |
- API エンドポイントにリクエストを送り、レスポンスのステータスコードと内容を確認する
- データベースへ書き込み、期待した状態になっているか確認する
5. E2Eテスト(End-to-End テスト)
Section titled “5. E2Eテスト(End-to-End テスト)”E2Eテストは、実際の利用者と同じ操作の流れを端から端まで通すテスト である。
ブラウザ操作 ↓ログイン画面でIDとパスワードを入力 ↓一覧画面が表示される ↓新しい本を追加する ↓一覧に追加した本が表示されているこのように、ブラウザ操作から始まり、バックエンド・データベースを通した結果まで確認する。
なぜ E2Eテストが必要か
Section titled “なぜ E2Eテストが必要か”ユニットテストや統合テストが通っていても、画面の設定ミスや経路の間違いで利用者が使えないことがある。
ユニットテスト OK統合テスト OKしかしブラウザの設定でページが表示されないE2Eテストは「利用者が実際に使える状態か」を確認する最後の砦である。
| 項目 | 内容 |
|---|---|
| 速度 | 遅い(ブラウザ操作・通信・DBアクセスを全て含む) |
| 安定性 | 最も不安定になりやすい(外部依存が多い) |
| 範囲 | 広い(アプリ全体の動作を通して確認) |
| 書きやすさ | 最も複雑 |
6. テストピラミッド
Section titled “6. テストピラミッド”3 種類のテストをどのくらいの割合で書くかの考え方として、テストピラミッド がある。
△ /E2E\ /-----\ / 統合 \ /---------\ / ユニット \ / \ピラミッドのイメージは次のとおりである。
| レベル | 量 | 理由 |
|---|---|---|
| ユニットテスト | 多い | 速く・安定していて・書きやすい |
| 統合テスト | 中程度 | 必要な連携確認に絞る |
| E2Eテスト | 少ない | 遅く・不安定になりやすいため重要な経路に限定する |
なぜピラミッド型が推奨されるのか
Section titled “なぜピラミッド型が推奨されるのか”E2Eテストだけに頼ると、次の問題が起きやすい。
全てE2Eテストにする ↓テスト実行が遅くなる ↓テストを実行する回数が減る ↓バグの発見が遅くなる逆にユニットテストを厚くすることで、速いフィードバックを得やすくなる。
ただしこれは絶対的な比率ではなく、アプリの性質や状況に合わせて調整する ものである。
7. テストダブル(モック・スタブ)
Section titled “7. テストダブル(モック・スタブ)”ユニットテストや統合テストでは、実際のデータベースや外部 API を使いたくない場面がある。 そのときに使うのが テストダブル である。
代表的なものを 2 つ押さえておく。
| 名前 | 役割 |
|---|---|
| スタブ | 固定の戻り値を返すニセの部品 |
| モック | 呼ばれた内容(引数・回数など)も記録して検証できるニセの部品 |
使い分けのイメージをコードで見てみる。
// スタブ:戻り値だけを固定するfunction stubBookRepository() { return { findAll: () => [ { id: 1, title: "JavaScript入門" }, { id: 2, title: "Git基礎" }, ] };}// → 「本が2件ある状態」を再現し、ビジネスロジックだけをテストできる
// モック:呼び出し内容も記録するfunction mockMailService() { const calls = []; return { send: (to, subject) => calls.push({ to, subject }), getCalls: () => calls, };}// → メールが正しい宛先・件名で1回だけ呼ばれたか、などを検証できる戻り値だけ固定したい → スタブ呼び出し回数や引数も確かめたい → モックただし、テストダブルを使いすぎると実際の動作と乖離する恐れがある。 何を確認したいか に合わせて、実物かスタブかを選ぶ。
8. どう使い分けるか
Section titled “8. どう使い分けるか”| 確認したいこと | 向いているテスト |
|---|---|
| 関数の計算が正しいか | ユニットテスト |
| API と DB が正しく連携するか | 統合テスト |
| ユーザーが実際に使えるか | E2Eテスト |
| 特定の条件(境界値・エラー)の動作 | ユニットテスト |
| ログイン〜操作〜確認の流れ全体 | E2Eテスト |
また、バグが見つかったらテストを書く という習慣も重要である。 同じバグが再び起きても、テストが守ってくれる。
回帰テストとは
Section titled “回帰テストとは”回帰テストとは、修正や機能追加のあとに、以前動いていた部分が壊れていないかを確認するテスト である。
新しい機能を追加した ↓既存のテストをすべて実行する ↓壊れていたテストが発見される ↓意図せず既存の動作を変えてしまったと分かる回帰テストは専用の「種類」ではなく、ユニットテスト・統合テスト・E2Eテストを使って、変更後に再実行する考え方 である。 テストを積み重ねておくほど、回帰テストの網が大きくなる。
| キーワード | 説明 |
|---|---|
| ユニットテスト | 関数・クラス単体の動作を確認 |
| 統合テスト | 複数の部品が組み合わさったときの動作を確認 |
| E2Eテスト | 利用者の操作フローを端から端まで通して確認 |
| テストピラミッド | ユニット多め・E2E少なめで速く安定したテスト群を作る考え方 |
| スタブ | 固定値を返すニセの部品 |
| モック | 呼び出し内容も記録できるニセの部品 |
| 回帰テスト | 修正後に以前動いていた部分が壊れていないかを確認するテスト |
次のステップ
Section titled “次のステップ”演習問題 に取り組んで、3 種類のテストの役割と使い分けを整理しよう。
その後は 7-2. TDD入門・コードレビューの観点 へ進もう。