テスト戦略 レッスン4
テスト駆動開発(TDD)
Red・Green・Refactorのサイクルでテストを先に書きながら実装を進めるTDDの基本を学ぶ
Red-Green-Refactorサイクル
TDDは、実装よりも先にテストを書き、以下の3ステップを短いサイクルで繰り返す開発手法です。
1. Red
まだ実装していない振る舞いに対して、失敗するテストを書く
2. Green
そのテストを通すための最小限の実装を書く(きれいさは後回し)
3. Refactor
テストが通っている状態を保ちながら、コードをきれいに整理する
サイクルを実際に回してみる
「割引後の価格を計算する関数」を例に、1テストずつ縦にスライスして進めます。すべてのテストを先に書き切ってから実装する「横スライス」は避け、 1つのテスト→1つの実装→リファクタリングを繰り返す「縦スライス」で進めます。
// ステップ1 (Red): 最初のテストを書く。実装はまだ無いので失敗する
it("割引がない場合は元の価格をそのまま返す", () => {
expect(applyDiscount(1000, 0)).toBe(1000);
});
// ステップ1 (Green): テストを通す最小限の実装
function applyDiscount(price, discountRate) {
return price;
}
// ステップ2 (Red): 次の振る舞いのテストを追加。これは失敗する
it("10%割引の場合は価格の90%を返す", () => {
expect(applyDiscount(1000, 0.1)).toBe(900);
});
// ステップ2 (Green): 両方のテストを通すために実装を更新
function applyDiscount(price, discountRate) {
return price * (1 - discountRate);
}
// ステップ3 (Refactor): 通っている状態を保ちながら、
// 例えば負の割引率をガードするなど整理していくTDDの効果と注意点
得られる効果
- • 実装前に「何をもって完了とするか」が明確になる
- • テストしやすい設計に自然と誘導される
- • 常にテストが通る状態を保ちながら進められる安心感
注意点
- • Red中はテストを通すこと以外のリファクタリングをしない
- • まだ実装していない将来の機能のテストを先取りして書かない
- • すべての開発にTDDが必須というわけではなく、探索的な設計段階では不向きなこともある
よくある誤解
TDDは「テストを先に全部書いてから実装をまとめて行う」ことではありません。 横スライスで進めると、実装の都合に合わせたテストになりがちで、 振る舞いを検証する本来の目的からズレてしまいます。縦スライスで小さく回すのが基本です。
ポイント
- • TDDはRed(失敗)→Green(最小実装)→Refactor(整理)を繰り返す手法
- • 1テスト→1実装の縦スライスで進め、横スライスは避ける
- • Red中はリファクタリングせず、まずテストを通すことに集中する
- • 将来のテストを先取りせず、今必要な振る舞いだけをテストする
確認クイズ
1 / 3TDDのRed-Green-Refactorサイクルの正しい順序はどれか?