Communitygithub.com

テスト駆動開発

《末日NPC都不太正常》エージェントスキルリポジトリ · 再利用可能なワークフロースキル

テスト駆動開発 とは?

このスキルは、AIエージェント(Claude Code、Cursor、Codexなど)向けに設計されたテスト駆動開発(TDD)のベストプラクティスワークフローを提供します。公開インターフェースを通じた振る舞いの検証に焦点を当て、実装の詳細に依存しないテスト作成を促進します。重要な特徴は、水平スライシング(全テストを先に書き、後で実装する)というアンチパターンを避け、トレーサー弾(1テスト→1実装の垂直スライス)を推奨することです。また、テスト作成時にはコードベースのCONTEXT.mdを参照し、ドメイン言語に合わせたテスト名やインターフェース語彙の統一を支援します。このスキルは、リファクタリングに強いテストスイートの構築と、効率的なRED-GREENサイクルによる開発プロセスを実現します。

対応~Claude Code~Codex CLI~Cursor
npx skills add madnpc/npc404-docs

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

テスト駆動開発 は何をしますか?

出力言語

デフォルトでは簡体字中国語を使用してユーザーとコミュニケーションし、テスト戦略、テスト説明、実装サマリーも簡体字中国語で記述します。ユーザーが明示的に他の言語を指定した場合、または既存のドキュメント言語で別の取り決めがある場合は、その取り決めに従います。コード、コマンド、製品名、および原文を維持する必要がある引用は強制的に翻訳しません。

哲学

中核原理: テストは公開インターフェースを通じて振る舞いを検証すべきであり、実装の詳細を検証すべきではありません。コードは完全に変更される可能性があります。テストは変更されるべきではありません。

良いテストは統合スタイルです。実際のコードパスを公開APIを通じて実行します。システムが何を行うかを記述し、どのように行うかを記述しません。良いテストは仕様のように読めます。「ユーザーは有効なカートでチェックアウトできる」は、どのような機能が存在するかを正確に示します。これらのテストは内部構造を気にしないため、リファクタリングに耐えます。

悪いテストは実装に結合しています。内部の協力者をモックし、プライベートメソッドをテストし、外部手段(データベースに直接クエリを実行するなど)で検証します。警告サイン:リファクタリング時にテストが壊れるが、振る舞いは変わっていない場合。内部関数の名前を変更しただけでテストが失敗する場合、そのテストは実装をテストしており、振る舞いをテストしていません。

例についてはtests.md、モッキングガイドラインについてはmocking.mdを参照してください。

アンチパターン: 水平スライシング

すべてのテストを先に書き、その後すべての実装を書かないでください。 これは「水平スライシング」であり、REDを「すべてのテストを書く」、GREENを「すべてのコードを書く」と見なすことです。

これは質の悪いテストを生み出します:

  • 一括で書かれたテストは実際の振る舞いではなく、想像上の振る舞いをテストします
  • 結局、ユーザー向けの振る舞いではなく、ものの形状(データ構造、関数シグネチャ)をテストすることになります
  • テストは実際の変更に鈍感になります。振る舞いが壊れてもテストはパスし、振る舞いが正常でもテストは失敗します
  • 実装を理解する前にテスト構造にコミットしてしまい、先走りになります

正しいアプローチ: トレーサー弾による垂直スライス。1テスト→1実装→繰り返し。各テストは前のサイクルから学んだことに応答します。コードを書いたばかりなので、どの振る舞いが重要で、どのように検証すべきかを正確に理解しています。

間違い(水平):
  RED:   test1, test2, test3, test4, test5
  GREEN: impl1, impl2, impl3, impl4, impl5

正しい(垂直):
  RED→GREEN: test1→impl1
  RED→GREEN: test2→impl2
  RED→GREEN: test3→impl3
  ...

ワークフロー

1. 計画

コードベースを探索する際は、CONTEXT.md(存在する場合)を読み、テスト名とインターフェース語彙がプロジェクトのドメイン言語に一致するようにし、対象領域のADRを尊重します。

コードを書く前に:

  • ユーザーと必要なインターフェース変更について確認する
  • ユーザーとテストすべき振る舞い(優先順位付け)について確認する
  • インターフェース境界が不明確な場合、コードベース設計原則を使用して深いモジュールの機会を特定する。ユーザーが明示的に要求しない限り、別のスキルを自動的に呼び出さない。
  • テストすべき振る舞い(実装手順ではない)をリストアップする
  • 計画についてユーザーの承認を得る

質問例: 「公開インターフェースはどのようなものにすべきですか? どの振る舞いが最も重要ですか?」

すべてをテストすることはできません。 どの振る舞いが最も重要かをユーザーと正確に確認してください。重要なパスと複雑なロジックにテストの労力を集中させ、すべての可能なエッジケースには注力しないでください。

2. トレーサー弾

システムに関する1つのことを確認する1つのテストを書きます:

RED:   最初の振る舞いのテストを書く → テストが失敗
GREEN: テストをパスする最小限のコードを書く → テストがパス

これがトレーサー弾です — パスがエンドツーエンドで機能することを証明します。

3. インクリメンタルループ

残りの各振る舞いについて:

RED:   次のテストを書く → 失敗
GREEN: パスする最小限のコード → パス

ルール:

  • 一度に1つのテスト
  • 現在のテストをパスするのに十分なコードだけ
  • 将来のテストを予測しない
  • テストは観察可能な振る舞いに焦点を当てる

4. リファクタリング

すべてのテストがパスした後、リファクタリング候補を探します:

  • 重複を抽出する
  • モジュールを深くする(複雑さをシンプルなインターフェースの背後に移動)
  • 自然な場所でSOLID原則を適用する
  • 新しいコードが既存コードについて何を明らかにするかを検討する
  • 各リファクタリングステップの後にテストを実行する

REDの状態ではリファクタリングしないでください。 まずGREENにしてください。

サイクルごとのチェックリスト

[ ] テストは振る舞いを記述しており、実装を記述していない
[ ] テストは公開インターフェースのみを使用している
[ ] テストは内部リファクタリングに耐えられる
[ ] コードはこのテストに対して最小限である
[ ] 推測的な機能は追加されていない

関連スキル