Agent skill
tdd
機能実装やバグ修正でテストを書く・変更する作業に使用。RED-GREEN-REFACTORサイクルを適用する。
Install this agent skill to your Project
npx add-skill https://github.com/TakumiOkayasu/dotfile-work/tree/main/claude/skills/TDD
SKILL.md
Test-Driven Development
トリガー条件
以下のすべてに該当する場合に発動する:
| 条件 | 例 |
|---|---|
| キーワード一致 | TDD、テスト駆動、テストファースト、RED-GREEN、失敗するテストを先に |
| 明示的指示 | 「テストを書いて」「テストから始めて」「再現テストを書いてから直して」 |
| 作業種別 | 新機能実装・バグ修正・リファクタリングでテストコードの作成・変更を伴う |
発動しない場合(除外条件):
| 除外 | 理由 |
|---|---|
| テストのインポート修正のみ | 振る舞いの変更なし |
| CIのyaml編集のみ | テストコード変更なし |
| E2Eテストの新規作成 | 本スキル対象外 |
| typo修正のみ | 実装変更なし |
前提条件
本スキルを開始する前に以下が満たされていること:
- プロジェクトにテストランナーが存在する(なければユーザーに確認)
- テスト実行コマンドが判明している
- 作業ブランチが作成済み(mainブランチ直接作業は禁止)
鉄則(すべてに優先)
- REDを確認するまで実装コードを書かない。 テスト実行→FAIL確認→実装の順序を守る。
- テストは仕様。 テストの期待する振る舞いをユーザー確認なしに変えない。
この2つに違反した場合: 実装コードを削除し、テストのRED確認からやり直す。
なぜ重要か: テストを先に書く理由は「正しい問いを立ててから答える」ため。RED確認のスキップは「答えに合う問いを後付けする」行為であり、テストの信頼性を根本から損なう。
ステップ0: プロジェクト検出(最初に必ず実行)
テストコードを書く前に、以下を順番に検出する:
- テストフレームワーク(Jest / Vitest / pytest / JUnit / RSpec / Go testing / Rust
#[test]等) - テストファイルの配置規約(
__tests__/、*.test.ts、*_test.go、tests/等) - テストの命名規約(既存テストから推測)
- テスト実行コマンド(
npm test、pytest、go test ./...、cargo test等) - 関連スキルの有無(git-workflow、refactoring、code-review 等)
1つでも検出できなければユーザーに確認する。推測で補わない。
ステップ1: 適用判断
テストの書き方はコードの状態に依存する。以下のシグナルで判断し、迷ったらユーザーに確認する。
仕様の確度を判断するシグナル
| 確度 | シグナル例 |
|---|---|
| 確定 | 型定義/APIスキーマがある、ユーザーが具体的な入出力を示した、既存テストがある |
| 方針のみ | 「〜したい」「〜な感じで」、インターフェースは未定だがゴールは明確 |
| 探索的 | 「試してみたい」「プロトタイプ」「どうなるか見たい」 |
| 不明 | 途中参加、レガシーコード、ドキュメントなし |
テスタビリティを判断するシグナル
| 状態 | シグナル例 |
|---|---|
| テスタブル | 純粋関数、DI済み、モック可能な境界がある |
| テスタブルでない | グローバル状態依存、DBを直接呼ぶ、外部APIが密結合、テストランナーすらない |
判断結果→行動
| 仕様 \ テスタビリティ | テスタブル | テスタブルでない |
|---|---|---|
| 確定 | TDDサイクルを回す | 特性テストで安全網→テスタブルにリファクタリング→TDD |
| 方針のみ | 統合テストを先に書き、詳細は実装しながら追加 | 特性テスト→テスタブルにする→統合テストから開始 |
| 探索的 | ユーザーに確認: 実装先行でよいか、仕様を先に固めるか | ユーザーに確認: 実装先行でよいか |
| 不明 | 特性テストで現状記録→変更箇所からTDD導入 | 特性テストで現状記録→テスタブルにする→TDD |
「探索的」は常にユーザー申告制。AIが勝手に判断して実装先行しない。
ステップ2: テストリスト作成
テストコードを書く前に、テストケースを自然言語でリストアップする。
// テストリスト例: ポイント計算機能
// □ 1000円の購入で10ポイント付与される
// □ 999円の購入ではポイント0
// □ 負の金額ではエラー
// □ ゴールド会員は2倍のポイント
// □ 0円の購入ではポイント0(境界値)
順序の決め方
- そのテストを通すために核となるインターフェースや型の決定が必要 → 優先度高
- 既存の実装に変更なく通せる → 優先度低
- 判断がつかない → 最も単純なケースから
テストリストは完璧でなくてよい。サイクル中に気づいたケースはリストに追加し、現在のサイクル完了後に着手する。
✅ リスト作成後、ユーザーに網羅性と優先順位を確認する。
「以下のテストケースで進めます。追加・変更・優先順位の調整はありますか?」
ステップ3: RED-GREEN-REFACTORサイクル
RED: 失敗するテストを書く
手順(この順序を守ること):
- テストケースを自然言語で言語化する(「何をテストするか」を明文化)
- テストコードを書く(1サイクルにつき1テストケースのみ)
- テストを実行する
- 意図した理由でFAILすることを出力で確認する(スキップ禁止)
確認ポイント:
- コンパイルエラーや設定ミスではなく、機能が未実装だからFAILしているか?
- テスト名から「対象」「条件」「期待結果」が読み取れるか?
❌ FAILを確認できない場合は実装に進まない。テストを見直すかユーザーに報告する。
GREEN: 最小限の実装でテストを通す
3つのテクニックを状況に応じて使い分ける:
| テクニック | いつ使うか | やること |
|---|---|---|
| 仮実装(Fake It) | 正しい一般化がすぐ書けない | ハードコードでテストを通す |
| 三角測量(Triangulation) | 仮実装では2つ目のテストを通せない | テスト追加で仮実装を一般化に追い込む |
| 明白な実装(Obvious) | 実装が一目で書ける | 直接正しい実装を書く。詰まったら仮実装へ |
GREENではテストを通す最小限の変更だけ行う。「ついでに」のリファクタリングはしない。
REFACTOR: テストを維持しながら改善
GREENの直後に毎回判断する。以下のいずれかに該当すれば実施:
- 直前のGREENで明らかな重複が生まれた
- 命名が意図を反映していない
- 1つの関数/メソッドが複数の責務を持っている
該当しなければスキップしてよい。REFACTORは義務ではなく機会。
やること: 重複除去、命名改善、責務分離。全テストがGREENのまま。
やらないこと: 新機能追加(REDに戻る)、テストの振る舞い変更。
ステップ4: 特性テスト(レガシーコード対応)
テストがない/信頼できないコードに対する段階的導入。
フェーズ1: 現状を記録する
現在の振る舞いを「そのまま記録する」テストを書く。正しいかどうかは問わない。
分離方法はプロジェクトの慣習に合わせる。慣習がなければ以下から選択:
describe("CHARACTERIZATION: ...")/@Tag("characterization")/ テスト名に[characterization]プレフィックス / ファイル名で分離
期待値に確信がない場合は // TODO: 仕様確認後に修正 コメントを付ける。
フェーズ2: 変更箇所にTDDを適用
- 変更対象の周辺に特性テストを書く(安全網)
- 新しい振る舞いのテストをRED-GREEN-REFACTORで追加
- 仕様が確認できた特性テストを通常テストに昇格
フェーズ3: 触った箇所から拡大
変更のたびにテストを充実させる。特性テストが減り、TDDテストが増える状態を目指す。
テストコード変更のルール
変更してよい場合
- テストケースの追加
- テストの構文エラー修正(意図を変えない範囲)
- ユーザーからの仕様変更指示に伴う期待値の変更
- テストヘルパー抽出など、振る舞いを変えないリファクタリング
- インターフェース変更に伴う呼び出し方の更新(期待する振る舞い自体は不変)
禁止
- 振る舞いが変わっていないのにアサーションの期待値を変える
- FAILするテストを削除して緑にする
- アサーションを緩くしてPASSさせる(
== 10→!= null等) - ユーザー確認なしでテストの期待する振る舞いを変更する
判断基準: 「テスト対象の公開インターフェースから見て、振る舞いは変わったか?」 変わっていなければ期待値は変えない。
出力形式テンプレート
テストリスト提示時
## テストリスト: [機能名]
□ [正常系1]: [入力] → [期待結果]
□ [正常系2]: [入力] → [期待結果]
□ [境界値]: [入力] → [期待結果]
□ [異常系1]: [入力] → [期待結果(例外/エラー)]
追加・変更・優先順位の調整はありますか?
RED確認報告時
## RED確認 ✅
テスト: [テスト名]
実行結果: FAIL
失敗理由: [実装が未存在 / 期待値 X に対し実際は Y]
→ 実装に進みます。
GREEN完了報告時
## GREEN完了 ✅
テスト: [テスト名]
実行結果: PASS
実装内容: [1〜2行で説明]
→ REFACTORを判断します。[実施する/スキップ(理由)]
サイクル完了報告時
## サイクル完了
完了: [N]件 PASS / 残り: [M]件
次のテストケース: [ケース名]
続行しますか?
AI固有の注意点
| よくある問題 | 対策 |
|---|---|
| テストと実装を1回のレスポンスで同時に出す | テスト出力→実行→RED確認→実装出力の順序を守る |
| 実装を見てからテストを逆算する | テストリストを先に作成する。実装コードを見る前にテストを書く |
弱いアサーション(toBeDefined() のみ) |
具体的な値を検証する。最低限「期待する戻り値」をアサート |
| 境界値・異常系の欠落 | テストリストに null、空文字列、0、負数、境界値を明示的に含める |
| モックの戻り値を推測で決める | モック対象の実際のインターフェース(型定義/APIドキュメント)を確認してから作成 |
| RED確認をスキップ | テスト実行コマンドを毎回実行し、FAILを出力で確認する |
RED確認のスキップが最も危険。 テストが最初からPASSする場合、そのテストは何も検証していない可能性がある。「意図した理由でFAILする」ことの確認が品質の要。
ユーザー確認ポイント
すべてのステップで確認を求めると開発リズムが崩れる。以下のタイミングで確認する:
| タイミング | 確認テンプレート |
|---|---|
| テストリスト作成後 | 「以下のテストケースで進めます。追加・変更・優先順位の調整はありますか?」 |
| 最初のRED-GREEN完了後 | 「この方向性(テストの書き方、実装アプローチ)で残りも進めてよいですか?」 |
| 仕様に曖昧さがある時 | 「[具体的な入力]の場合、期待する振る舞いは[A]と[B]のどちらですか?」 |
| テストの期待値を変更したい時 | 「テスト[名前]の期待値を[旧]→[新]に変更してよいですか? 理由: [理由]」 |
| 一連のサイクル完了後 | 「[N]件のテストがすべてPASSしています。次のステップに進みますか?」 |
方向性が確定した後の反復的なRED-GREEN-REFACTORは、まとめて進めてよい。
コミット戦略
全テストがPASSした状態でのみコミットする。コミットメッセージはプロジェクト慣習に従う(git-workflowスキルがあれば参照)。
| タイミング | コミット例 |
|---|---|
| GREEN完了(テスト+実装) | feat: implement [feature] with tests |
| REFACTOR完了 | refactor: [description] |
| 特性テスト追加 | test: add characterization test for [target] |
| バグ修正(再現テスト+修正) | fix: [description] |
RED(FAILするテスト)単独ではコミットしない。RED+GREENをセットでコミットする。
関連スキルとの連携
| スキル | 連携ポイント |
|---|---|
| refactoring | REFACTORフェーズで参照。テストが緑の状態を維持しながら構造改善 |
| git-workflow | コミットメッセージ規約、ブランチ命名に従う |
| code-review | テストの品質レビュー観点を参照 |
| systematic-debugging | RED確認で予期しないエラーが出た場合の根本原因分析 |
禁止事項
| 禁止操作 | 理由 |
|---|---|
| RED確認をスキップして実装に進む | テストの信頼性を損なう |
| テストを書かずに実装する(ユーザー承認なし) | TDDの目的に反する |
| 振る舞いが変わっていないのにテストの期待値を書き換える | 仕様の改ざん |
| 複数テストケースを1サイクルで同時に扱う | サイクルの粒度違反 |
| FAILするテストを削除/無効化して緑にする | 問題の隠蔽 |
| 既存テストをユーザー確認なしに変更・削除する | 仕様の無断変更 |
| FAILする状態でコミットする | CI破壊 |
| モックの戻り値をインターフェース確認なしに推測で決める | ハルシネーション |
| 「探索的」かどうかをAIが勝手に判断する | ユーザー申告制 |
| テストと実装を同一レスポンスで同時出力する | RED確認の迂回 |
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
performance-optimization
パフォーマンス最適化やプロファイリング時に使用。計測手法、ボトルネック特定、負荷テスト、レポート出力をカバー。
systematic-debugging
バグやテスト失敗に遭遇した際に使用。修正前の4フェーズ根本原因分析を強制。
interface-first-design
機能追加・クラス設計・interface設計・依存関係整理・責務分割時に使用。疑似コードから interface→クラス→TDD→実装の順で設計する。TDDスキルの前段。
consultation
実装中に判断が必要になった時、技術選定・設計相談が必要な時に使用。相談テンプレートで構造化された問題提示を強制。
test-coverage-guard
既存テストの信頼性を検証し、偽陽性を検出・排除するガードレール。テストがGREENになった後に発動する。
refactoring
振る舞いを変えずにコード構造を改善する際に使用。
Didn't find tool you were looking for?