TDDの基本
ストーリー
「テストケースの設計技法は分かったな。 次はテストの『書き順』について話そう」
松本先輩がホワイトボードに3色の円を描いた。
「Red, Green, Refactor。TDDの基本サイクルだ。 テストを先に書いてから実装する。 最初は違和感があるかもしれないが、 慣れると手放せなくなるぞ」
TDD(テスト駆動開発)とは
TDD(Test-Driven Development)は、実装コードを書く前にテストコードを書く開発手法です。Kent Beck が提唱しました。
Red-Green-Refactor サイクル
┌──────────────┐
│ 1. Red │ 失敗するテストを書く
│ (赤) │
└──────┬───────┘
│
▼
┌──────────────┐
│ 2. Green │ テストを通す最小限の実装
│ (緑) │
└──────┬───────┘
│
▼
┌──────────────┐
│ 3. Refactor │ コードを改善する
│ (リファクタ) │
└──────┬───────┘
│
└──→ 1 に戻る
TDDの実践:FizzBuzz
サイクル1: 数字をそのまま返す
1. Red: 失敗するテストを書く
typescript
// fizzbuzz.test.ts
import { fizzBuzz } from './fizzbuzz';
describe('fizzBuzz', () => {
it('1 を渡すと "1" を返す', () => {
expect(fizzBuzz(1)).toBe('1');
});
});テスト結果: ❌ FAIL
→ fizzBuzz 関数がまだ存在しない
2. Green: テストを通す最小限の実装
typescript
// fizzbuzz.ts
export function fizzBuzz(n: number): string {
return String(n);
}テスト結果: ✅ PASS
3. Refactor: 改善の余地なし → 次のサイクルへ
サイクル2: 3の倍数で Fizz
1. Red
typescript
it('3 を渡すと "Fizz" を返す', () => {
expect(fizzBuzz(3)).toBe('Fizz');
});テスト結果: ❌ FAIL → "3" が返ってきた
2. Green
typescript
export function fizzBuzz(n: number): string {
if (n % 3 === 0) return 'Fizz';
return String(n);
}テスト結果: ✅ PASS
サイクル3: 5の倍数で Buzz
1. Red
typescript
it('5 を渡すと "Buzz" を返す', () => {
expect(fizzBuzz(5)).toBe('Buzz');
});2. Green
typescript
export function fizzBuzz(n: number): string {
if (n % 3 === 0) return 'Fizz';
if (n % 5 === 0) return 'Buzz';
return String(n);
}サイクル4: 15の倍数で FizzBuzz
1. Red
typescript
it('15 を渡すと "FizzBuzz" を返す', () => {
expect(fizzBuzz(15)).toBe('FizzBuzz');
});2. Green
typescript
export function fizzBuzz(n: number): string {
if (n % 15 === 0) return 'FizzBuzz';
if (n % 3 === 0) return 'Fizz';
if (n % 5 === 0) return 'Buzz';
return String(n);
}3. Refactor: コードを改善
typescript
export function fizzBuzz(n: number): string {
const isFizz = n % 3 === 0;
const isBuzz = n % 5 === 0;
if (isFizz && isBuzz) return 'FizzBuzz';
if (isFizz) return 'Fizz';
if (isBuzz) return 'Buzz';
return String(n);
}TDDのメリット
| メリット | 説明 |
|---|---|
| 設計が改善される | テストしやすいコード = 疎結合なコード |
| テストカバレッジが高い | 全ての実装にテストが先行する |
| 過剰設計を防ぐ | テストを通す最小限の実装から始める(YAGNI) |
| ドキュメントになる | テストが仕様を表す |
| デバッグ時間が減る | バグが入った時点で即座に気づく |
TDDの注意点
| 注意点 | 説明 |
|---|---|
| 学習コスト | 慣れるまで時間がかかる |
| 全てに適用しない | UIやプロトタイプには不向きな場合がある |
| テストの保守 | テストもコードであり、保守が必要 |
| 過度な依存 | TDDだけで品質が保証されるわけではない |
TDDの3つの法則
Uncle Bob(Robert C. Martin)が提唱した TDD の3つの法則です。
1. 失敗する テストを書く前に、プロダクションコードを書いてはならない
2. 失敗する最小限のテスト以上のテストを書いてはならない
(コンパイルエラーも失敗に含む)
3. 現在失敗しているテストを通す以上のプロダクションコードを
書いてはならない
まとめ
| 項目 | ポイント |
|---|---|
| TDDの定義 | テストを先に書いてから実装する開発手法 |
| 基本サイクル | Red(失敗テスト)→ Green(最小実装)→ Refactor(改善) |
| メリット | 設計改善、高カバレッジ、過剰設計防止 |
| 適用範囲 | ビジネスロジック、アルゴリズムに特に有効 |
チェックリスト
- Red-Green-Refactor サイクルを説明で きる
- 簡単な関数でTDDを実践できる
- TDDのメリットと注意点を理解した
- TDDの3つの法則を説明できる
次のステップへ
TDDの基本を学んだら、次はカバレッジと品質指標について学びます。テストの量と質をどう測定するか理解しましょう。
推定読了時間: 20分