tdd について
tddは、振る舞いを検証するテストと小さな実装ステップで開発を進めるスキルです。公開インターフェースを重視した段階的なレッド・グリーンサイクルにより、内部実装に依存するテストを避けます。
主な機能
- 01公開APIを通じて観察可能な振る舞いをテスト
- 021テストずつ進めるレッド・グリーンサイクル
- 03重要な振る舞いの計画と優先順位付け
- 04テスト通過後にのみリファクタリング
活用シーン
- 01段階的なテストサイクルで機能を開発
- 02内部リファクタリングに耐えるテストの設計
- 03重要な経路のテストを優先
- 04実装前のテスト計画の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ brianlovin/ agent-config --skill tddインストール後、Claude Code で/tddを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
deep-modules.mdinterface-design.mdmocking.mdrefactoring.mdtests.md詳細
テスト駆動開発
哲学
基本原則:テストでは実装の詳細ではなく、公開インターフェースを通じて動作を検証します。コードは全面的に変更しても構いませんが、テストは変更せずに済むべきです。
良いテストは、実際のコードパスを公開 API 経由で実行する、統合テスト形式のテストです。システムが「どのように」動作するかではなく、「何を」するかを記述します。良いテストは仕様書のように読めます。「有効なカートでユーザーがチェックアウトできる」とあれば、どのような機能があるのかが正確にわかります。内部構造を気にしないため、こうしたテストはリファクタリングを経ても機能し続けます。
悪いテストは、実装に密結合しています。内部の協力者をモックしたり、プライベートメソッドをテストしたり、インターフェースを使わずにデータベースへ直接クエリするなど、外部の手段で検証したりします。警告サインは、動作が変わっていないのにリファクタリングでテストが壊れることです。内部関数の名前を変更してテストが失敗するなら、そのテストは動作ではなく実装をテストしています。
例については tests.md を、モックのガイドラインについては mocking.md を参照してください。
アンチパターン:水平スライス
テストをすべて先に書いてから、実装をすべて書いてはいけません。 これは「水平スライス」です。RED を「テストをすべて書くこと」、GREEN を「コードをすべて書くこと」と捉えるやり方です。
この方法ではひどいテストが生まれます。
- まとめて書かれたテストは、実際の動作ではなく、_想像上の_動作をテストします
- ユーザーに見える動作ではなく、物事の_形_(データ構造や関数シグネチャなど)をテストすることになります
- 実際の変更に対する感度が低くなり、動作が壊れても成功し、問題がないのに失敗するテストになります
- 実装を理解する前にテスト構造を決めてしまい、先走ることになります
正しいアプローチ:トレーサーバレットを使った垂直スライスです。テストを 1 つ書く → 実装を 1 つ行う → 繰り返す。各テストは、前のサイクルで学んだことを反映します。コードを書いたばかりなので、重要な動作とその検証方法を正確に把握できます。
WRONG (horizontal):
RED: test1, test2, test3, test4, test5
GREEN: impl1, impl2, impl3, impl4, impl5
RIGHT (vertical):
RED→GREEN: test1→impl1
RED→GREEN: test2→impl2
RED→GREEN: test3→impl3
...
ワークフロー
1. 計画
コードを書く前に、次のことを行います。
- 必要なインターフェースの変更についてユーザーに確認する
- テストする動作をユーザーに確認し、優先順位を付ける
- ディープモジュール(小さなインターフェース、深い実装)の活用機会を特定する
- テスト容易性を考慮してインターフェースを設計する
- 実装手順ではなく、テストする動作を列挙する
- 計画についてユーザーの承認を得る
次のように尋ねます。「公開インターフェースはどのような形にするべきですか?テストで最も重視すべき動作はどれですか?」
すべてをテストすることはできません。 最も重要な動作をユーザーに具体的に確認します。考えられるすべてのエッジケースではなく、重要な経路と複雑なロジックにテストの労力を集中させます。
2. トレーサーバレット
システムについて 1 つのことを確認するテストを 1 つ書きます。
RED: Write test for first behavior → test fails
GREEN: Write minimal code to pass → test passes
これがトレーサーバレットです。経路がエンドツーエンドで機能することを証明します。
3. インクリメンタルループ
残りの動作ごとに、次の手順を繰り返します。
RED: Write next test → fails
GREEN: Minimal code to pass → passes
ルール:
- 一度にテストを 1 つだけ行う
- 現在のテストに合格するために必要なコードだけを書く
- 将来のテストを先回りしない
- 観察可能な動作にテストを集中させる
4. リファクタリング
すべてのテストに合格したら、リファクタリング候補を探します。
- 重複を抽出する
- モジュールを深くする(複雑さをシンプルなインターフェースの背後に移す)
- 自然な場合に SOLID 原則を適用する
- 新しいコードから既存のコードについて何がわかるかを検討する
- リファクタリングの各ステップ後にテストを実行する
RED の状態でリファクタリングしてはいけません。 まず GREEN にします。
サイクルごとのチェックリスト
[ ] Test describes behavior, not implementation
[ ] Test uses public interface only
[ ] Test would survive internal refactor
[ ] Code is minimal for this test
[ ] No speculative features added