この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:2
更新日時:2026-06-10 10:22:51
タイトル: 単体テスト
本稿は 単体テスト (UT: Unit Test) に関する記事です。単体テストは、関数・メソッド・クラスなどプログラムの「単位 (ユニット)」を独立して動作確認するテストのことで、ソフトウェア開発工程の中で最も基礎的かつ最も頻繁に実行されるテストです。
単体テストの位置づけ
| テスト工程 | 対象 | 実施タイミング |
| 単体テスト (UT) | 関数・クラス・モジュールなど最小単位 | 実装直後 / コミット時 / CI 都度 |
| 結合テスト (IT) | 複数モジュールの連動 | 機能単位の実装後 |
| システムテスト (ST) | システム全体 | 結合後 |
| 受入テスト (UAT) | 業務要件 | リリース前 |
近年はテストピラミッドの考え方に基づき、UT を多く、結合・E2E は少なめに配置するのが主流です。
単体テストの目的とメリット
- 仕様の保証 — 「この入力ならこの出力」を機械で検証
- リファクタリングの安全網 — 内部実装を変えても挙動が変わっていないか即確認
- 仕様のドキュメント化 — テストコード自体が「使い方」のサンプルになる
- バグの早期検出 — 開発者の手元で発見できればコストが圧倒的に低い
- 設計品質の向上 — テストしやすい設計 = 凝集度が高く依存が少ない設計
AAA / Given-When-Then パターン
単体テストの構造は次のように整理すると読みやすくなります。
| AAA | Given-When-Then | 内容 |
| Arrange | Given | 前提条件・テストデータの準備 |
| Act | When | テスト対象の処理を実行 |
| Assert | Then | 結果の検証 |
主な単体テストフレームワーク
| 言語 | フレームワーク |
| Java | JUnit 5、TestNG、Spock |
| Kotlin | JUnit 5、Kotest、MockK |
| PHP | PHPUnit、Pest |
| Python | pytest、unittest (標準) |
| JavaScript / TypeScript | Jest、Vitest、Mocha、Jasmine |
| Ruby | RSpec、Minitest |
| Go | 標準 testing、Testify |
| C# | xUnit.net、NUnit、MSTest |
| Rust | 標準 #[test] |
| Swift | XCTest |
典型的なテスト例 (JUnit 5)
|
class CalculatorTest {
@Test
void add_正の数同士は和を返す() {
var calc = new Calculator(); // Arrange
int result = calc.add(2, 3); // Act
assertEquals(5, result); // Assert
}
}
|
モック / スタブ / フェイク
| 呼び方 | 役割 |
| スタブ (Stub) | 呼ばれたら決められた値を返すだけ。状態の検証はしない |
| モック (Mock) | 呼ばれ方 (引数・回数) を検証する |
| フェイク (Fake) | 本物に近い動作をする軽量実装 (例: インメモリDB) |
代表的なモックライブラリ: Java の Mockito、PHP の Mockery / Prophecy、Python の unittest.mock、JS の jest.mock、Kotlin の MockK。
良い単体テストの条件 (FIRST 原則)
| 頭文字 | 意味 |
| Fast | 速い (1テスト数ms〜数十ms) |
| Isolated | 他のテスト/外部 (DB・API) に依存しない |
| Repeatable | 何度実行しても同じ結果 |
| Self-validating | 結果は OK / NG が自動判定される |
| Timely | 実装と同時 (またはTDDで先) に書く |
カバレッジ
- 命令網羅 (Statement Coverage) — どの行が実行されたか
- 分岐網羅 (Branch Coverage) — if/else の両方が通ったか
- 条件網羅 — 条件式の各真偽パターンを試したか
- カバレッジは「目安」であり 100% を目指す数値ゲームではない。重要分岐に集中する
注意点・アンチパターン
- 外部 I/O 依存 — 本物の DB / API / ファイルを直接叩くテストは UT ではなく結合テスト寄り
- テストが壊れやすい — 内部実装を細かく検証しすぎ、リファクタで頻繁に壊れるテスト
- テストがあるだけ —
assertNotNull(x) のみで本質を検証していない
- テスト間依存 — 実行順で結果が変わるのは NG
- カバレッジ稼ぎ — アサートのないテストでカバレッジだけ上げない
関連
- 親カテゴリ: 開発工程
- 関連プロセス: 結合テスト・E2Eテスト・CI/CD