単体テストとV字モデルの対応関係
V字モデルでは、左辺の各設計フェーズと右辺のテストフェーズが一対一で対応します。単体テスト(Unit Test)は詳細設計と対応しており、モジュール・クラス・メソッド単位の動作を検証するフェーズです。
単体テストの目的は「詳細設計書に記述されたロジック通りにコードが動くか」を確認することです。外部システムや他モジュールへの依存を排除し、テスト対象のユニットを孤立させて検証します。これにより、欠陥を早期に発見でき、修正コストを最小限に抑えられます。
INPUTドキュメント — 何を読んでテストを設計するか
単体テスト仕様書を作成するにあたり、必ず参照すべきドキュメントがあります。テスト設計者はこれらを熟読し、テストケースを網羅的に導出します。
| INPUTドキュメント | 参照目的 | 確認箇所 |
|---|---|---|
| 詳細設計書(クラス設計書) | テスト対象のメソッド仕様・引数・戻り値・例外定義を把握する | メソッドシグネチャ・前提条件・事後条件・例外ケース |
| シーケンス図(詳細版) | 処理の流れ・分岐条件・外部呼び出しの有無を確認する | 条件分岐・ループ・外部サービス呼び出しのタイミング |
| エラーコード・メッセージ定義書 | 異常系テストケースの期待値(例外クラス・メッセージ)を確認する | エラーコード一覧・例外クラス名・ログ出力内容 |
| データ項目定義書 | 入力値の型・桁数・必須制約から境界値・同値クラスを導出する | データ型・最大/最小値・NULL許容・フォーマット |
💡 INPUTが不完全な場合
詳細設計書が不十分な状態でテスト仕様書を書こうとすると、テストケースの漏れが生じます。単体テスト仕様書の作成開始前に、設計書のレビューが完了していることを確認してください。設計と実装の乖離はテストフェーズで最初に発覚するケースが多いため、発見次第設計書にフィードバックする体制を整えることが重要です。
作成ドキュメントの構成
単体テストフェーズで作成するドキュメントは、大きく「単体テスト仕様書」と「テストコード」の2種類です。それぞれの役割と記載内容を以下に整理します。
① 単体テスト仕様書
テスト仕様書はテストケースを文書化したものです。自動化ツール(JUnit等)で全てコードに落とす場合でも、テスト設計の意図・観点・期待値を別途ドキュメントとして残しておくことで、レビューやメンテナンス時の可読性が向上します。
| 記載項目 | 内容 | 例 |
|---|---|---|
| テスト対象 | クラス名・メソッド名 | UserService#createUser() |
| テストケースID | 一意の識別子 | UT-USER-001 |
| テスト観点 | 何を確認するか(正常系/異常系/境界値) | 正常系:正しいメールアドレスで登録成功 |
| 前提条件 | テスト実行前のデータ状態・モック設定 | DBにユーザーが0件、メール送信はモック |
| 入力値 | メソッドに渡す引数・パラメータ | email="test@example.com", name="田中" |
| 期待結果 | 戻り値・例外・副作用(DB更新等) | Userオブジェクト返却、DBにレコード1件挿入 |
| 対応テストメソッド | JUnit等のテストクラス・メソッド名 | UserServiceTest#testCreateUser_Success() |
② テストコード(JUnit 5)
テスト仕様書をそのまま自動化したものがテストコードです。JUnit 5 では @Test・@ParameterizedTest・@BeforeEach などのアノテーションを使い、テストケースを構造化します。テストコードはプロダクションコードと同等の品質で管理します。
✅ テストコードの命名規則
テストメソッド名は「対象メソッド_条件_期待結果」の形式が可読性を高めます。例:createUser_withValidEmail_shouldReturnUser()。この命名規則をプロジェクト全体で統一することで、テスト仕様書との対応関係が明確になります。
確認ポイントと品質基準
単体テストの確認ポイントは「正常系」「異常系」「境界値」の3軸で整理するのが基本です。さらに「同値分割」の考え方を用いてテストケースを効率的に絞り込みます。
確認ポイント一覧
| 観点 | 確認内容 | 優先度 |
|---|---|---|
| 正常系 | 有効な入力値でメソッドが期待通りの結果を返すこと | 必須 |
| 異常系(例外) | 不正入力・NULL・制約違反で適切な例外がスローされること | 必須 |
| 境界値 | 最大値・最小値・ゼロ・空文字・1件・最大件数など | 必須 |
| 条件分岐網羅 | if/switch の全分岐(true/false)がテストされること | 推奨 |
| 副作用の検証 | DBへの書き込み・外部サービス呼び出し回数・ログ出力などを検証 | 推奨 |
| カバレッジ | 命令網羅率(C0)80%以上、分岐網羅率(C1)70%以上 | 推奨 |
カバレッジ計測の考え方
カバレッジはテストの充足度を示す指標ですが、「100%を目指すこと」が目的ではありません。以下の点を理解した上で運用します。
- C0(命令網羅):全命令が少なくとも1回実行されること。最低限の基準。
- C1(分岐網羅):全分岐の真偽両方が実行されること。C0より厳しい基準で推奨。
- C2(条件網羅):複合条件の全組み合わせを網羅。コストが高いため一般的ではない。
JaCoCo(Java)では C0/C1 が計測可能で、Maven/Gradle プラグインとして CI/CDパイプラインに組み込み、カバレッジが閾値を下回った場合にビルドを失敗させる設定が推奨されます。
利用ツール — JUnit 5 / Mockito / JaCoCo
JUnit 5
Java の単体テストフレームワークの標準です。JUnit 5(Jupiter)は JUnit 4 から大幅に拡張され、パラメータ化テスト・ネストしたテストクラス・拡張機構などが強化されています。
| アノテーション | 用途 |
|---|---|
@Test | テストメソッドを定義する |
@ParameterizedTest | 複数の入力値でテストを繰り返す(境界値テストに有効) |
@BeforeEach / @AfterEach | 各テスト前後に共通の前処理・後処理を実行する |
@Nested | テストを条件ごとにネストしたクラスでグループ化する |
@DisplayName | テスト結果に表示される日本語の説明を付与する |
assertThrows() | 例外がスローされることを検証する |
Mockito
外部依存(Repository・外部API・メール送信など)をモック化するフレームワークです。テスト対象を孤立させて純粋なロジック検証が可能になります。
@Mock/@InjectMocks:モックオブジェクトの生成とDIを自動化when().thenReturn():モックの返却値を定義verify():モックが期待通りに呼ばれたかを検証(副作用の確認に使用)ArgumentCaptor:モックに渡された引数を捕捉して詳細検証
JaCoCo(カバレッジ計測)
JaCoCo は Java のコードカバレッジ計測ツールです。Maven・Gradle プラグインとして利用でき、HTMLレポートの生成とCI連携が容易です。カバレッジレポートは pull request ごとに自動生成してレビュー時の確認材料にすることを推奨します。
よくある落とし穴と対策
⚠️ 実装を写しただけのテスト
「メソッドの処理をそのままアサートしている」テストは意味がありません。テストは詳細設計書の仕様を基準に書くべきです。実装ではなく仕様から期待値を導出する習慣を徹底してください。
⚠️ テスト間の依存関係
あるテストが別のテストの実行結果に依存する状態(テスト順序依存)は危険です。@BeforeEach でテストデータを毎回初期化し、テストを完全に独立させてください。Mockito の @ExtendWith(MockitoExtension.class) を使えばモックの初期化も自動化できます。
⚠️ カバレッジ数値だけを追う
カバレッジ100%でも、アサートが不十分なテストは欠陥を見落とします。「コードの行を通過させること」ではなく「仕様の条件を検証すること」が目的です。C0/C1 の閾値達成と仕様カバレッジの両面で品質を評価してください。
まとめ
単体テストフェーズで定義すべき3つのポイントを整理します。
- INPUT:詳細設計書・シーケンス図・エラー定義書・データ項目定義書を必ず参照する
- 作成ドキュメント:テスト仕様書(ID・観点・入力値・期待結果)+テストコード(JUnit 5)
- 確認ポイント:正常系・異常系・境界値・分岐網羅・カバレッジ(C0 80%以上)
JUnit 5 + Mockito + JaCoCo の組み合わせは Java プロジェクトにおけるデファクトスタンダードです。CI/CDパイプラインに組み込み、プルリクエストごとにテストとカバレッジを自動検証する体制を整えることで、品質の継続的な維持が可能になります。
✅ 次のステップ
単体テスト仕様書の作成が完了したら、次は「結合テスト仕様書」へ。モジュール間の連携・API契約・DBの整合性を検証するフェーズに進みます。