概要
TDD(Test-Driven Development)とは、
**「コードを書き始める前に、そのコードが満たすべき仕様(テスト)を書く」**という開発手法である。
この手法の本質は「テストを書く」ことではなく、
**“思考を仕様ベースで始める”**ことにある。
本稿では、TDDの思想・流れ・メリットと、Vitest+TypeScriptを用いた最小構成での実践例を交えながら、
**「なぜTDDが設計を変えるのか」**を構造的に解き明かす。
1. TDDとは何か:定義と誤解
TDDは「テストを書いてから実装する」という説明では足りない。
本質は以下の3つの原則にある:
- 🔴 Red:失敗するテストを書く(仕様を書く)
- 🟢 Green:テストが通る最小限のコードを書く
- 🛠️ Refactor:構造を改善し、意味を保つ
実装駆動ではなく、仕様駆動であることがTDDの根幹にある。
2. なぜTDDは「先にテストを書く」のか
- 実装より先に「何を期待するか」が明確になる
- コードが過剰に書かれず、最小限で済む
- 依存や外部要因を先に意識できるため、疎結合な設計になる
テストは「品質保証」ではなく、**「設計プロンプト」**である
3. 実践:TDDでFizzBuzzを設計する(TypeScript + Vitest)
npm create vite@latest tdd-fizzbuzz --template vanilla-ts
cd tdd-fizzbuzz
npm i
npm i -D vitest
src/fizzbuzz.ts
(まだ空)
// 空の実装(Green前)
src/fizzbuzz.test.ts
import { describe, expect, it } from 'vitest';
import { fizzbuzz } from './fizzbuzz';
describe('fizzbuzz', () => {
it('returns number for non-multiples of 3 or 5', () => {
expect(fizzbuzz(1)).toBe('1');
});
});
Red:テストが失敗する
ReferenceError: fizzbuzz is not defined
Green:最小限の実装を書く
export function fizzbuzz(n: number): string {
return String(n);
}
再度テスト:
✓ returns number for non-multiples of 3 or 5
Red → Green → 次の仕様を追加
it('returns Fizz for multiples of 3', () => {
expect(fizzbuzz(3)).toBe('Fizz');
});
it('returns Buzz for multiples of 5', () => {
expect(fizzbuzz(5)).toBe('Buzz');
});
it('returns FizzBuzz for multiples of 15', () => {
expect(fizzbuzz(15)).toBe('FizzBuzz');
});
Green:拡張された実装でテストを通す
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);
}
Refactor:構造を洗練させる
- 条件分岐の順序を整理
- 再利用可能な条件チェッカーを抽出可能
4. 設計観点から見るTDDの本質
- 🔍 仕様が明確になることで、設計がシンプルになる
- 🧩 依存を隔離しやすく、モジュール単位の責務が明確になる
- 🚦 Red→Greenの明快なフィードバックが、設計の正しさを保証する
実装は「仕様を通すための必要最小限の部品」になる。
5. TDDが破壊する3つの常識
従来の思考 | TDD的思考 |
---|---|
コード → テスト | テスト → コード |
実装のために考える | 期待される振る舞いから設計する |
UIやAPIをまず作る | 使用者視点の仕様から導入する |
結語
TDDは「実装をテストする」手法ではない。
それは**“実装されるべき仕様を明示し、それにコードを従わせる構造的思考法”**である。
- 仕様を書くことで、設計が始まる
- 実装は仕様を満たす最小限にする
- テストは「確認」ではなく、「設計のトリガー」として機能する
TDDとは、
“コードを書き始める前に「何を保証したいか」を思考し、実装を仕様に従属させるための知的戦略である。”