テスト戦略 レッスン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 / 3

TDDのRed-Green-Refactorサイクルの正しい順序はどれか?