mcpField
T
tdd

tdd

github.com/parcadeiテスト・品質3.9k472 回インストール39 週間前に更新
リポジトリ

tdd について

tddは、テストを先に失敗させてから最小限の実装で通す、テストファーストの開発手順を定めるスキルです。計画、テスト作成、実装、検証のエージェント順も示します。

主な機能

  1. 01本番コードより先に失敗するテスト
  2. 02Red-Green-Refactorの手順
  3. 03テストに基づく最小限の実装
  4. 04計画と検証を含むエージェント順序
  5. 05テストと全体の検証チェックリスト

活用シーン

  1. 01テストファーストで機能を実装
  2. 02バグ修正に回帰テストを追加
  3. 03TDDの各段階でエージェントを連携
  4. 04完了前に新旧テストを検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/parcadei/continuous-claude-v3 --skill tdd

インストール後、Claude Code で/tddを入力して読み込まれたか確認します。

詳細

/tdd - テスト駆動開発ワークフロー

厳格なTDDワークフローです。まずテストを書き、その後に実装します。

使用するタイミング

  • 「TDDでXを実装して」
  • 「この機能をテストファーストで作って」
  • 「Xのテストを書いてから実装して」
  • テストカバレッジが重要な機能
  • 回帰テストが必要なバグ修正

TDDの考え方

概要

まずテストを書きます。失敗することを確認します。テストを通す最小限のコードを書きます。

基本原則: テストが失敗するところを確認していなければ、そのテストが適切なものを検証しているかはわかりません。

ルールの文言に違反することは、ルールの精神に違反することです。

鉄の掟

NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST

テストより先にコードを書いた場合は、それを削除してやり直してください。

例外はありません:

  • 「参考用」として残さない
  • テストを書きながら「調整」しない
  • 見ない
  • 削除とは、削除することです

テストをもとに新たに実装してください。以上です。

レッド・グリーン・リファクター

RED - 失敗するテストを書く

何が起きるべきかを示す、最小限のテストを1つ書きます。

良い例:

test('retries failed operations 3 times', async () => {
  let attempts = 0;
  const operation = () => {
    attempts++;
    if (attempts < 3) throw new Error('fail');
    return 'success';
  };

  const result = await retryOperation(operation);

  expect(result).toBe('success');
  expect(attempts).toBe(3);
});

明確な名前で、実際の動作を1つ検証しています。

悪い例:

test('retry works', async () => {
  const mock = jest.fn()
    .mockRejectedValueOnce(new Error())
    .mockResolvedValueOnce('success');
  await retryOperation(mock);
  expect(mock).toHaveBeenCalledTimes(3);
});

曖昧な名前で、コードではなくモックを検証しています。

要件:

  • 動作は1つ
  • 明確な名前
  • 実際のコードを使う(避けられない場合を除き、モックは使わない)
REDを検証 - 失敗することを確認する

必須です。絶対に省略しないでください。

npm test path/to/test.test.ts
# or
pytest path/to/test_file.py

次の点を確認してください:

  • テストが失敗する(エラーではない)
  • 失敗メッセージが想定どおり
  • 機能がないために失敗している(タイプミスではない)

テストが通る場合は? 既存の動作をテストしています。テストを修正してください。 テストでエラーが発生する場合は? エラーを修正し、正しく失敗するまで再実行してください。

GREEN - 最小限のコードを書く

テストを通すための最もシンプルなコードを書きます。

良い例:

async function retryOperation<T>(fn: () => Promise<T>): Promise<T> {
  for (let i = 0; i < 3; i++) {
    try {
      return await fn();
    } catch (e) {
      if (i === 2) throw e;
    }
  }
  throw new Error('unreachable');
}

テストを通すために必要な分だけです。

悪い例:

async function retryOperation<T>(
  fn: () => Promise<T>,
  options?: {
    maxRetries?: number;
    backoff?: 'linear' | 'exponential';
    onRetry?: (attempt: number) => void;
  }
): Promise<T> {
  // YAGNI - over-engineered
}

機能を追加したり、ほかのコードをリファクタリングしたり、テストの範囲を超えて「改善」したりしないでください。

GREENを検証 - テストが通ることを確認する

必須です。

npm test path/to/test.test.ts

次の点を確認してください:

  • テストが通る
  • ほかのテストも引き続き通る
  • 出力がクリーン(エラーや警告がない)

テストが失敗する場合は? テストではなくコードを修正してください。 ほかのテストが失敗する場合は? すぐに修正してください。

REFACTOR - 整理する

グリーンになった後に限り、次の作業を行います:

  • 重複を取り除く
  • 名前を改善する
  • ヘルパーを抽出する

テストが通る状態を保ってください。動作は追加しないでください。

よくある言い訳

言い訳実際のところ
「テストするほどでもなく簡単」簡単なコードでも壊れます。テストは30秒で書けます。
「後でテストする」最初からテストが通っても、何も証明できません。
「後からテストしても同じ目的を達成できる」後からのテスト=「これは何をするのか?」。テストファースト=「これは何をするべきか?」。
「すでに手動でテストした」その場限りの確認は体系的なテストとは異なります。記録がなく、再実行もできません。
「X時間分を削除するのは無駄」サンクコストの誤謬です。検証されていないコードを残すのは技術的負債です。
「参考用に残して、先にテストを書く」そのコードに合わせてしまいます。それは後からのテストです。削除とは、削除することです。
「まず調査が必要」かまいません。調査用のコードは破棄し、TDDで始めてください。
「テストが難しいのは設計が不明瞭だから」テストの声に耳を傾けてください。テストしにくいものは、使いにくいものです。
「TDDでは遅くなる」TDDはデバッグより速いです。実践的に進めるなら、テストファーストです。
「手動テストのほうが速い」手動テストではエッジケースを証明できません。変更のたびに再テストすることになります。

危険信号 - 作業を止めてやり直す

  • テストより先にコードを書く
  • 実装後にテストを書く
  • テストがすぐに通る
  • テストが失敗した理由を説明できない
  • テストを「後で」追加する
  • 「今回だけ」と正当化する
  • 「すでに手動でテストした」
  • 「後からテストしても同じ目的を達成できる」
  • 「参考用に残す」または「既存のコードに合わせる」

これらはすべて、コードを削除してTDDでやり直すべきだという意味です。

検証チェックリスト

作業を完了とする前に、次を確認してください:

  • 追加した関数/メソッドすべてにテストがある
  • 実装前に、各テストが失敗することを確認した
  • 各テストは想定どおりの理由で失敗した(タイプミスではなく、機能がないため)
  • 各テストを通すための最小限のコードを書いた
  • すべてのテストが通る
  • 出力がクリーン(エラーや警告がない)
  • テストには実際のコードを使用している(避けられない場合に限り、モックを使用)
  • エッジケースとエラーを網羅している

すべてにチェックを付けられませんか? TDDを省略しています。最初からやり直してください。

行き詰まったとき

問題解決策
テスト方法がわからない望ましい API を書きます。まずアサーションを書きます。人間のパートナーに相談します。
テストが複雑すぎる設計が複雑すぎます。インターフェースをシンプルにします。
すべてをモックする必要があるコードの結合度が高すぎます。依存性注入を使います。
テストのセットアップが大規模ヘルパーを切り出します。それでも複雑ですか?設計をシンプルにします。

ワークフローの実行

ワークフローの概要

┌────────────┐    ┌──────────┐    ┌──────────┐    ┌───────────┐
│   plan-    │───▶│ arbiter  │───▶│  kraken  │───▶│ arbiter  │
│   agent    │    │          │    │          │    │           │
└────────────┘    └──────────┘    └──────────┘    └───────────┘
   Design          Write           Implement        Verify
   approach        failing         minimal          all tests
                   tests           code             pass

エージェントの順序

#エージェント役割出力
1plan-agentテストケースと実装方針を設計するテスト計画
2arbiter失敗するテストを書く(RED フェーズ)テストファイル
3krakenテストを通す最小限のコードを実装する(GREEN フェーズ)実装
4arbiterすべてのテストを実行し、問題がないことを確認するテストレポート

基本原則

NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST

各エージェントは TDD の契約に従います。

  • arbiter は最初に必ず失敗するテストを書く
  • kraken はテストを通すための最小限のコードを書く
  • arbiter はテストスイート全体が通ることを確認する

実行

フェーズ 1:テストケースを計画する
Task(
  subagent_type="plan-agent",
  prompt="""
  Design TDD approach for: [FEATURE_NAME]

  Define:
  1. What behaviors need to be tested
  2. Edge cases to cover
  3. Expected test structure

  DO NOT write any implementation code.
  Output: Test plan document
  """
)
フェーズ 2:失敗するテストを書く(RED)
Task(
  subagent_type="arbiter",
  prompt="""
  Write failing tests for: [FEATURE_NAME]

  Test plan: [from phase 1]

  Requirements:
  - Write tests FIRST
  - Run tests to confirm they FAIL
  - Tests must fail because feature is missing (not syntax errors)
  - Create clear test names describing expected behavior

  DO NOT write any implementation code.
  """
)
フェーズ 3:実装する(GREEN)
Task(
  subagent_type="kraken",
  prompt="""
  Implement MINIMAL code to pass tests: [FEATURE_NAME]

  Tests location: [test file path]

  Requirements:
  - Write ONLY enough code to make tests pass
  - No additional features beyond what tests require
  - No "improvements" or "enhancements"
  - Run tests after each change

  Follow Red-Green-Refactor strictly.
  """
)
フェーズ 4:検証する
Task(
  subagent_type="arbiter",
  prompt="""
  Validate TDD implementation: [FEATURE_NAME]

  - Run full test suite
  - Verify all new tests pass
  - Verify no existing tests broke
  - Check test coverage if available
  """
)

適用される TDD ルール

  1. arbiter は実装コードを書けません
  2. kraken はテストされていない機能を追加できません
  3. 実装前にテストが失敗しなければなりません
  4. 実装後にテストが成功しなければなりません

例

User: /tdd Add email validation to the signup form

Claude: Starting /tdd workflow for email validation...

Phase 1: Planning test cases...
[Spawns plan-agent]
Test plan:
- Valid email formats
- Invalid email formats
- Empty email rejection
- Edge cases (unicode, long emails)

Phase 2: Writing failing tests (RED)...
[Spawns arbiter]
✅ 8 tests written, all failing as expected

Phase 3: Implementing minimal code (GREEN)...
[Spawns kraken]
✅ All 8 tests now passing

Phase 4: Validating...
[Spawns arbiter]
✅ 247 tests passing (8 new), 0 failing

TDD workflow complete!

リファクタリングフェーズ(任意)

GREEN の後に、リファクタリングフェーズを追加できます。

Task(
  subagent_type="kraken",
  prompt="""
  Refactor: [FEATURE_NAME]

  - Clean up code while keeping tests green
  - Remove duplication
  - Improve naming
  - Extract helpers if needed

  DO NOT add new behavior. Keep all tests passing.
  """
)

コメント