テスト駆動開発(Test-Driven Development)
まず失敗するテストを書きましょう。テストが失敗するのを確認します。テストを通すための最小限のコードを書きます。リファクタリングします。 すぐにパスするテストは何も証明しません — それはバグを捕捉したことがない証拠です。
鉄則: 失敗するテストなしにプロダクションコードを書かないでください。テストより先にコードを書いてしまったら、そのコードを削除してやり直しましょう。「後で参照用に残す」は裏返しの「後付けテスト」です — 削除は削除を意味します。
使用するタイミング
- 新機能や振る舞いを実装するとき
- バグを修正するとき(まずテストで再現 — 「Prove-Itパターン」)
- リファクタリングや既存の振る舞いを変更するとき
- トリガーキーワード: "tdd", "test-driven", "red green refactor", "テスト駆動開発", "赤緑リファクタ", "テスト駆動"
使用しない場合: 既に書かれたコードのテスト生成(その場合は test-generation スキルを使用してください);使い捨てプロトタイプや純粋な設定変更(直接実装してください)。
例外(ユーザーに確認が必要): 使い捨てプロトタイプ、生成コード、振る舞いに影響を与えない純粋な設定変更。
手順
0. まずスタックを把握する
サイクル自体は普遍的ですが、コマンドはそうではありません。最初のテストの前に、このリポジトリのテスト方法を調べましょう:package.json / pyproject.toml / Cargo.toml / pom.xml / go.mod を読み、./gradlew、Makefile、CIワークフロー、既存のテストファイルの命名規則を確認します。npm test を前提にせず — RED、GREEN、最終検証のすべてのステップでリポジトリ固有のコマンドを使用します。
1. RED — 1つの失敗するテストを書く
1つの振る舞い、1つのテスト、1つの垂直スライス(最後のサイクルで学んだことに基づいて応答するトレーサー弾)。あなたが望むテストを書きましょう — それは実装ではなく、望ましいAPIを記述するものです。仕様として名前を付けます("test1" ではなく "rejects empty email")。
シーム(テスト対象の公開インターフェース)を書く前に合意します。未確認のシームでテストを書かない — 事前にシームを合意することで、すべてのエッジケースではなく、重要なパスにテスト労力を集中できます。モックよりも実際のコードを優先します;依存関係を代用する必要がある場合は、最も単純な代用を使用します(Real > Fake > Stub > Mock — references/test-strategy.md 参照)。モックは境界を分離するためのものであり、テスト対象そのものを分離するためのものではありません。
2. REDの確認 — 失敗を確認する
フォーカスしたテストコマンドを実行します。以下の点を確認します:
- 失敗すること(エラーではない — エラーの場合はセットアップを修正して再実行)
- 正しい理由で失敗すること(機能が欠けている、タイポではない)
- すぐにパスするテストは既存の振る舞いをテストしていることになります — テストを修正してください
3. GREEN — 最小限のコードを書く
テストを通す最もシンプルなコード。推測による機能、"柔軟性"、隣接コードのリファクタリングは不要。YAGNI。プロダクションクラスにテスト専用メソッド(destroy()、reset())を追加しない — クリーンアップはテストユーティリティに記述します。
4. GREENの確認 — パスを確認する
フォーカスしたテストコマンドを実行し、次に全テストスイートを実行します。以下の点を確認します:
- 新しいテストがパスすること
- 他のテストが壊れていないこと(壊れた場合はすぐに修正 — 飛ばさない)
- 出力が完全であること(警告なし、スキップされたテストなし)
5. REFACTOR — クリーンアップ
グリーンの状態でのみ:ヘルパーの抽出、名前の改善、重複の除去。リファクタリングのステップごとにテストを実行します。振る舞いは追加しません。リファクタリングはレビューステージに属し、Red→Greenの実装サイクルには含まれません。
6. コミット
テストと実装を1つの垂直スライスとして一緒にコミットします。その後、次の失敗するテストを開始します。
バグ修正 — Prove-Itパターン
修正から始めないでください。バグを再現するテストを書き(REDで存在を確認)、修正します(GREENで修正が機能することを証明)。テストは回帰防止として残ります。再現テストなしにバグを修正しないでください。
確認
- すべての新しい振る舞いに対して、最初に失敗したテストが存在する
- リポジトリ固有のテストコマンドでフルスイートがパスする
- バグ修正には、修正前に失敗した再現テストが含まれている
- テスト名は振る舞いを記述し、実装を記述していない
- スキップまたは無効なテストがない;プロダクションコードにテスト専用メソッドがない
参照
- ${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md — すべてのスキルが共有する規律
- references/test-strategy.md — テストピラミッド、テスト代用の階層(Real > Fake > Stub > Mock)、DAMP over DRY
- references/testing-anti-patterns.md — モックの誤用、テスト専用メソッド、部分モック、ゲート関数
- references/mocking.md — モックを使うタイミング、モックしやすくするための設計
- references/good-tests.md — 良いテストと悪いテストの例、同語反復テスト