tdd について
tddは、動作を確認するテストと小さなレッド・グリーンのサイクルで開発を進めるスキルです。公開インターフェースを重視し、段階的に実装してテスト通過後にリファクタリングします。
主な機能
- 01観察可能な動作を検証するテスト
- 02公開インターフェースのテスト指針
- 03一度に一つのレッド・グリーンサイクル
- 04段階的な実装
- 05グリーン後のリファクタリング
活用シーン
- 01動作重視のテスト範囲の計画
- 02機能の小刻みな実装
- 03内部実装に結合したテストの回避
- 04テスト通過後のリファクタリング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mksglu/ context-mode --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. 計画
コードベースを調査するときは、プロジェクトのドメイン用語集を使い、テスト名やインターフェースの用語をプロジェクトの言葉に合わせてください。また、変更する領域の ADR を尊重してください。
コードを書く前に、次のことを行います。
- 必要なインターフェースの変更についてユーザーに確認する
- テストする振る舞いについてユーザーに確認し、優先順位を付ける
- 深いモジュール(小さなインターフェースと深い実装)にできる箇所を特定する
- テスト容易性を考慮してインターフェースを設計する
- 実装手順ではなく、テストする振る舞いを列挙する
- 計画についてユーザーの承認を得る
「公開インターフェースはどのような形にすべきですか? テストするうえで最も重要な振る舞いは何ですか?」と尋ねてください。
すべてをテストすることはできません。 どの振る舞いが最も重要かを、必ずユーザーに確認してください。考えられるすべてのエッジケースではなく、重要な経路と複雑なロジックにテストの労力を集中させます。
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
mattpocock/skills からベンダー提供されたものです。コミット b843cb5 — MIT License。更新手順については skills/UPSTREAM-CREDITS.md を参照してください。