test-driven-development について
開発者向けのテスト駆動開発スキルで、実装前に失敗するテストを書き、RED-GREEN-REFACTORのサイクルを必須とします。各段階に条件を設け、変更ごとのテスト実行と最小限の実装を求めます。
主な機能
- 01実装前に失敗するテストを1件作成
- 02テストを通すための最小限の実装
- 03各フェーズで全テストを実行
- 04動作を変えずにリファクタリング
- 05対象の動作に応じたテスト選択
活用シーン
- 01機能を動作単位で段階的に実装
- 02バグ修正時の回帰テスト追加
- 03動作の変化を確認しながらリファクタリング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pixel-process-ug/ superkit-agents --skill test-driven-developmentインストール後、Claude Code で/test-driven-developmentを入力して読み込まれたか確認します。
同梱ファイルtesting-anti-patterns.md
詳細
テスト駆動開発
概要
TDDでは、RED-GREEN-REFACTORのサイクルを絶対に守るべき規律として徹底します。失敗するテストを書き、最小限のコードでパスさせ、その後にコードを整理します。このスキルにより、テストされていない本番コードが存在することを防ぎ、実装のすべての行が検証済みの要件に基づくようにします。
開始時に宣言してください:「RED-GREEN-REFACTORのサイクルでテスト駆動開発スキルを使用します。」
絶対原則
┌─────────────────────────────────────────────────────────────────┐
│ HARD-GATE: NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST │
│ │
│ This is non-negotiable. There are no exceptions. If you are │
│ writing production code and there is no failing test demanding │
│ that code, you are violating this skill. STOP immediately │
│ and write the test first. │
└─────────────────────────────────────────────────────────────────┘
フェーズ1:RED(失敗するテストを書く)
目標: 正しい理由で失敗するテストをちょうど1つ書きます。
作業
- 次に実装する最小単位の動作を特定します
- その動作が存在することを検証するテストを書きます
- テストスイートを実行し、新しいテストが失敗することを確認します
- エラーメッセージを読み、正しい理由(構文エラーやインポートエラーではなく、機能の不足)で失敗していることを確認します
- 間違った理由で失敗した場合は、正しく失敗するまでテストを修正します
停止 — 厳格なゲート:次の条件を満たすまでGREENに進まないでください:
- テストを作成し、保存した
- テストスイートを実行した
- 新しいテストが失敗する
- 失敗の理由が正しい(意図した動作をテストしている)
フェーズ2:GREEN(テストをパスさせる)
目標: 失敗しているテストをパスさせるために、必要最小限の本番コードを書きます。
作業
- 失敗しているテストをパスさせるのに必要なコードだけを書きます
- リファクタリングしないでください。整理しないでください。最適化しないでください
- テストをパスさせるために値をハードコードしてもかまいません
- テストスイート全体を実行します
- すべてのテストをパスさせる必要があります(新しいテストだけではありません)
停止 — 厳格なゲート:次の条件を満たすまでREFACTORに進まないでください:
- 本番コードを書いた
- テストスイート全体を実行した
- すべてのテストをパスした(新規および既存)
- 必要以上のコードを書いていない
フェーズ3:REFACTOR(整理する)
目標: 動作を変えずに、コードの品質を向上させます。
作業
- 重複、適切でない命名、長いメソッド、コードの臭いがないか確認します
- 一度に1つだけリファクタリングします
- 変更のたびにテストスイート全体を実行します
- テストが1つでも失敗したら、すぐにリファクタリングを元に戻します
- コードが整理されるまで続けます
停止 — 厳格なゲート:次の条件を満たすまで、次のREDに進まないでください:
- コードが整理され、読みやすい
- リファクタリング後もすべてのテストがパスする
- リファクタリング中に動作を変更していない
厳格なゲートの徹底
┌─────────────────────────────────────────────────────────────┐
│ HARD-GATE: PHASE COMPLETION CHECK │
│ │
│ Before moving to next phase, ALL items in the │
│ STOP MARKER checklist must be satisfied. │
│ │
│ If ANY item is not satisfied: │
│ → STOP │
│ → Complete the missing item │
│ → Re-verify ALL items │
│ → ONLY THEN proceed │
└─────────────────────────────────────────────────────────────┘
ウォッチモードの規律
ファイル(テストまたは本番コード)を変更するたびに、関連するテストスイートを実行します。例外はありません。
| 作業 | テストを実行するか | 期待される結果 |
|---|---|---|
| テストを書く | はい | 失敗(RED) |
| 本番コードを書く | はい | パス(GREEN) |
| コードをリファクタリングする | はい | パス(引き続きGREEN) |
| その他の編集 | はい | リグレッションなし |
テストランナーがウォッチモードに対応している場合は、それを使用してください。対応していない場合は、保存するたびに手動でテストを実行します。
判定表:テストタイプの選択
| テスト対象の動作 | テストタイプ | フレームワークの例 |
|---|---|---|
| 純粋関数のロジック | ユニットテスト | Vitest, pytest, cargo test |
| APIエンドポイントのリクエスト/レスポンス | インテグレーションテスト | Supertest, httpx |
| データベースクエリの正確性 | インテグレーションテスト | Testcontainers |
| UIコンポーネントのレンダリング | ユニットテスト | React Testing Library |
| ユーザーの一連のワークフロー | E2Eテスト | Playwright |
| エラー処理の経路 | ユニットテスト | Vitest, pytest |
サイクルの例
Requirement: "Users can register with email and password"
Behavior List:
1. Registration with valid email and password succeeds
2. Registration fails if email is empty
3. Registration fails if password is too short
4. Registration fails if email is already taken
Cycle 1 - Behavior 1:
RED: test_registration_with_valid_email_and_password_succeeds → FAIL (no register function)
GREEN: def register(email, password): return User(email=email) → PASS
REFACTOR: rename variable for clarity → PASS
Cycle 2 - Behavior 2:
RED: test_registration_fails_if_email_is_empty → FAIL (no validation)
GREEN: add if not email: raise ValueError → PASS
REFACTOR: extract validation to separate method → PASS
...continue for each behavior...
チェックリスト:TDDで新機能を始める
- コードを書く前に、要件を十分に理解する
- 要件を具体的な動作のリストに分解する
- 動作を最も簡単なものから最も複雑なものの順に並べる
- 最初の動作のタスクを作成する
- REDフェーズに入り、最初の動作について失敗するテストを書く
- GREENフェーズに入り、パスさせるための最小限のコードを書く
- REFACTORフェーズに入り、コードを整理する
- 次の動作のタスクを作成し、手順5から繰り返す
- すべての動作を実装したら、テストスイート全体を実行する
- 完了を宣言する前に
verification-before-completionを呼び出す
テスト品質基準
各テストは次の条件を満たす必要があります。
| 基準 | 定義 |
|---|---|
| 高速 | 秒ではなく、ミリ秒単位で完了する |
| 独立性 | テスト間で状態を共有せず、テストの実行順序に依存しない |
| 再現性 | 毎回同じ結果になり、不安定にならない |
| 自己検証可能 | 手動で解釈する必要がなく、合格または不合格が明確である |
| 適時性 | 本番コードを書く前に作成する(これこそが要点です) |
各テストは次のようにします。
- 1つの振る舞いまたはシナリオをテストする
- シナリオと期待される結果を説明する、わかりやすい名前を付ける
- Arrange-Act-Assert(または Given-When-Then)の構造に従う
- 必要最小限のセットアップを使用する
- 実装の詳細ではなく、結果を検証する
アンチパターン/よくある間違い
| アンチパターン | 誤りである理由 | 正しい方法 |
|---|---|---|
| 先に本番コードを書く | TDD の目的を損ない、テストが合格するように形作られてしまう | 必ず先にテストを書く |
| コードを書く前に複数のテストを書く | テストをまとめて書くと、段階的な設計の妨げになる | 1つのテストにつき、1サイクル |
| 初回の実行でテストに合格する | テストが間違っているか、振る舞いがすでに存在している | 先に進む前に調査する |
| GREEN フェーズに5分以上かける | 一度に多くのコードを書きすぎている | 単純化し、テストをより具体的にする |
| コードに合うようにテストを変更する | テストが振る舞いを定義し、コードはテストに合わせるべき | テストではなく、コードを修正する |
| REFACTOR フェーズを省略する | 技術的負債が急速に蓄積する | 毎サイクル、リファクタリングする |
| 変更のたびにテストを実行しない | リグレッションを見落とす | 保存のたびにテストを実行する |
正当化を防ぐ
| 言い訳 | 現実 |
|---|---|
| 「ほんの小さな変更です」 | 小さな変更が本番環境の障害を引き起こします。テストしてください。 |
| 「テストは後で書きます」 | 書かないでしょう。書いたとしても、仕様を定義するのではなく合格するように形作られているため、テストの質は低くなります。 |
| 「これは単なるリファクタリングです」 | リファクタリングは、思っている以上に頻繁に振る舞いを変えます。テストスイートが、振る舞いが変わっていないことを証明します。 |
| 「これは動くとわかっています」 | わかっていません。そう思っているだけです。テストがそれを証明します。 |
| 「テストを書くと遅くなります」 | テストなしのデバッグは、10倍も時間がかかります。 |
| 「このコードは単純すぎてテストできません」 | テストするには単純すぎるなら、間違えるには単純すぎるということです。つまり、テストも簡単に書けます。書いてください。 |
| 「依存関係のせいでテストできません」 | それなら設計に結合の問題があります。設計を修正してください。 |
| 「テストを書くほうがコードを書くより難しいです」 | それは、要件を十分に理解していないということです。テストを書くことで、要件を明確にできます。 |
| 「手動で確認すればいいです」 | 手動での確認は再現性がなく、記録もされず、信頼できません。 |
| 「これは使い捨て/プロトタイプのコードです」 | プロトタイプのコードは本番コードになることがあります。今テストするか、後で後悔してください。 |
| 「フレームワークのせいでテストが難しいです」 | フレームワークのテスト用ユーティリティを使うか、ロジックをフレームワークから切り離してください。 |
| 「時間に追われています」 | 20分を超える作業では、TDD のほうが速く進められます。時間に追われているときこそ、TDD が必要です。 |
危険信号
次のいずれかに気づいたら、作業を中断して見直してください。
| 危険信号 | 意味 | 対処 |
|---|---|---|
| 失敗するテストがない状態で本番コードを書く | 即時の違反 | 中断して、テストを書く |
| 初回の実行でテストにすぐ合格する | テストが間違っているか、振る舞いがすでに存在している | 先に進む前に調査する |
| GREEN フェーズに5分以上かかる | コードを書きすぎている | 単純化する。テストをより具体的にする |
| リファクタリングで振る舞いが変わる | テストカバレッジに抜けがある | 不足しているテストを追加する |
| 合格させるためにテストを変更する | 要件と実装が逆転している | テストに合わせてコードを修正する |
| 本番コードを書く前に複数のテストを書く | テストをまとめて書くと、目的が損なわれる | 一度に1つのテストを書く |
| 変更後にテストスイートを実行しない | リグレッションを見つけられない | 必ず、毎回テストを実行する |
統合ポイント
| スキル | 関連性 |
|---|---|
verification-before-completion | TDD の作業が完了したと主張する前に、必ず実行する必要があります |
systematic-debugging | REFACTOR 中にテストが予期せず失敗した場合は、デバッグに切り替えます |
code-review | TDD で機能を実装した後、テストスイートに漏れがないかレビューします |
acceptance-testing | 受け入れ基準が、TDD サイクルで扱う動作の一覧を決めます |
planning | 計画によって、機能を TDD サイクルに適した動作に分割します |
testing-strategy | テスト戦略でフレームワークを定め、TDD でサイクルを定めます |
TDD におけるテストの種類
| 種類 | 範囲 | 速度 | 作成するタイミング |
|---|---|---|---|
| ユニット(主要) | 個々の関数、メソッド、クラス | ミリ秒 | すべての動作について RED フェーズで作成します |
| 統合(副次) | コンポーネント間の連携 | 秒 | ユニットテストで個々の動作をカバーした後に作成します |
| E2E(補助) | ユーザーのワークフロー全体 | 秒〜分 | ユニットテストと統合テストが十分に整った後、重要な経路について作成します |
スキルの種類
厳格 — RED-GREEN-REFACTOR サイクルは必須であり、順序の変更、省略、結合はできません。次のフェーズに進む前に、各フェーズの HARD-GATE を満たす必要があります。最初に失敗するテストを書かずに、本番コードを書いてはいけません。