mcpField
T
tdd-workflow

tdd-workflow

github.com/hieutrtrテスト・品質851 回インストール38 週間前に更新
リポジトリ

tdd-workflow について

機能開発やバグ修正をテスト駆動で進めるためのスキルです。RED、GREEN、REFACTOR、コミットの段階に分け、変更ごとのテスト実行を定めています。

主な機能

  1. 01RED-GREEN-REFACTOR サイクルの実施
  2. 02失敗するテストを一度に一つ作成
  3. 03テストを通す最小限の実装
  4. 04変更のたびにテストを実行
  5. 05サイクル完了後のコミット

活用シーン

  1. 01新機能をテスト優先で実装
  2. 02バグ修正前に回帰テストを作成
  3. 03リファクタリング前に特性テストを追加

インストール

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

$npx skills add https://github.com/hieutrtr/ai1-skills --skill tdd-workflow

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

詳細

TDD ワークフロー

使用するタイミング

次の場合に、このスキルを有効にします。

  • ユーザーが TDD、テストファースト、またはレッド・グリーン・リファクタリングを明示的に求めている
  • テストファーストの価値がある新しい関数、メソッド、エンドポイント、またはコンポーネントを実装する
  • 回帰テストを先に書くべきバグを修正する
  • ユーザーが「先にテストを書いて」「これを TDD で」「レッド・グリーン・リファクタリング」と言っている

次の場合は、このスキルを使用しないでください。

  • 設定ファイル、環境設定、または静的コンテンツ
  • 1 行の修正や些細な変更
  • 探索的なプロトタイピングや概念実証コード
  • 単独で有意義なテストができないコード
  • テストパターンの詳細(テストの書き方は pytest-patterns または react-testing-patterns を使用)

手順

TDD サイクル
┌─────────────────────────────────────────────────────┐
│                                                     │
│   ┌─────┐     ┌───────┐     ┌──────────┐          │
│   │ RED │ ──→ │ GREEN │ ──→ │ REFACTOR │ ──→ ...  │
│   └─────┘     └───────┘     └──────────┘          │
│                                                     │
│   Write ONE    Write MINIMUM   Clean up code        │
│   failing      code to make    while ALL tests      │
│   test         it pass         stay GREEN            │
│                                                     │
└─────────────────────────────────────────────────────┘
フェーズ 1:RED — 失敗するテストを書く
  1. 期待される動作を説明するテストをちょうど 1 つ書きます
  2. テストは具体的である必要があります。複数ではなく、1 つの動作をテストします
  3. テストスイートを実行し、新しいテストが失敗することを確認します
  4. エラーメッセージから、何が不足しているかが明確にわかるようにします

バックエンド(pytest):

pytest tests/unit/test_user_service.py::test_create_user_returns_user -x
# Expected: FAILED (function/class does not exist yet)

フロントエンド(Vitest):

npx vitest run src/hooks/useAuth.test.ts --reporter=verbose
# Expected: FAILED (hook/component does not exist yet)

RED フェーズのルール:

  • 要件を表現する最もシンプルなテストを書きます
  • 正しい理由(実装がないこと)でテストが失敗するようにします(構文エラーではありません)
  • 一度に複数の失敗するテストを書かないでください
  • コードがまだ存在していなくても、コードを配置する場所からインポートします
フェーズ 2:GREEN — テストを通す
  1. 失敗しているテストを通すために必要な最小限のコードを書きます
  2. 追加の機能、エラー処理、またはエッジケースを加えないでください
  3. 値をハードコードしたり、シンプルな実装を使ったりしてもかまいません
  4. テストスイートを実行し、新しいテストだけでなく、すべてのテストが通ることを確認します
# Backend
pytest tests/unit/test_user_service.py -x

# Frontend
npx vitest run src/hooks/useAuth.test.ts

GREEN フェーズのルール:

  • 最小限のコードとは、本当に最小限のコードです。定数でテストを満たせるなら、定数を使います
  • テストで求められていないコードを追加しないでください
  • このフェーズではリファクタリングしないでください
  • このフェーズではテストを追加で書かないでください
  • テストが通ったら、REFACTOR に進みます
フェーズ 3:REFACTOR — 整理する
  1. すべてのテストが通った状態を保ちながら、コードの品質を向上させます
  2. 重複を取り除きます(DRY)
  3. 命名と可読性を改善します
  4. 必要に応じて関数やクラスを切り出します
  5. 変更するたびにテストを実行し、必ず通り続けることを確認します
# After each refactoring change
pytest tests/ -x    # Must pass
npx vitest run      # Must pass

REFACTOR フェーズのルール:

  • すべての変更でテストが通り続けるようにします
  • プロダクションコードとテストコードの両方をリファクタリングします
  • 新しい機能を追加しないでください(その場合は新たな RED フェーズが必要です)
  • テストを壊した場合は、直ちにリファクタリングを取り消します
フェーズ 4:コミット

REFACTOR フェーズが正常に完了したら:

  1. すべての変更(テストと実装)をステージングします
  2. 内容がわかるメッセージを付けてコミットします
  3. 次の動作に向けてフェーズ 1(RED)に戻ります
TDD の厳格なルール

このスキルが有効な場合、次のルールは必ず守ってください。

  1. 失敗するテストを先に書かずに、プロダクションコードを書かないでください
  2. 一度に複数の失敗するテストを書かないでください
  3. テストで求められていない機能を追加しないでください
  4. 変更のたびに必ずテストを実行してください
  5. GREEN-REFACTOR サイクルが正常に完了するたびに、必ずコミットしてください
  6. RED-GREEN-REFACTOR サイクルは必ず短く保ってください(数時間ではなく、数分)
バックエンドの TDD フロー(pytest)
1. Write test:     tests/unit/test_user_service.py::test_create_user_returns_user
2. Run:            pytest tests/unit/test_user_service.py::test_create_user_returns_user -x
3. See:            FAILED - ImportError or AssertionError
4. Implement:      app/services/user_service.py (minimum code)
5. Run:            pytest tests/unit/test_user_service.py -x
6. See:            PASSED
7. Refactor:       Clean up, run tests again
8. Commit:         "Add UserService.create_user"
9. Next test:      test_create_user_rejects_duplicate_email
フロントエンドの TDD フロー(Testing Library)
1. Write test:     src/components/UserCard.test.tsx::renders user name
2. Run:            npx vitest run src/components/UserCard.test.tsx
3. See:            FAILED - module not found
4. Implement:      src/components/UserCard.tsx (minimum code)
5. Run:            npx vitest run src/components/UserCard.test.tsx
6. See:            PASSED
7. Refactor:       Clean up, run tests again
8. Commit:         "Add UserCard component"
9. Next test:      calls onEdit when button clicked
バグ修正の TDD フロー

バグを修正するときは、必ずバグを再現する失敗テストから始めます。

1. Reproduce:      Understand the bug and its trigger condition
2. Write test:     Test that exercises the exact scenario that causes the bug
3. Run:            Confirm FAILED (the test reproduces the bug)
4. Fix:            Implement the minimum fix
5. Run:            Confirm PASSED (bug is fixed)
6. Refactor:       Clean up if needed
7. Commit:         "Fix: [describe the bug]"

これにより、テストがバグを検出するため、バグが再発しないことが保証されます。

例

TDD:UserService.create_user(3 サイクル)

サイクル 1 — RED: create_user がユーザーを返すことをテストします

async def test_create_user_returns_user(db_session):
    service = UserService(db_session)
    user = await service.create_user(UserCreate(email="[email protected]", password="12345678", display_name="A"))
    assert user.email == "[email protected]"
    assert user.id is not None

GREEN: 基本的なロジックで UserService.create_user を実装します。 REFACTOR: パスワードのハッシュ化を切り出します。コミットします。

サイクル 2 — RED: メールアドレスが重複している場合にエラーが発生することをテストします

async def test_create_user_rejects_duplicate_email(db_session):
    service = UserService(db_session)
    await service.create_user(UserCreate(email="[email protected]", password="12345678", display_name="A"))
    with pytest.raises(ConflictError):
        await service.create_user(UserCreate(email="[email protected]", password="87654321", display_name="B"))

GREEN: 挿入前に重複をチェックします。 REFACTOR: 整理します。コミットします。

サイクル 3 — RED: パスワードがハッシュ化されることをテストします

async def test_create_user_hashes_password(db_session):
    service = UserService(db_session)
    user = await service.create_user(UserCreate(email="[email protected]", password="12345678", display_name="A"))
    assert user.hashed_password != "12345678"
    assert verify_password("12345678", user.hashed_password)

GREEN: サイクル 1 のリファクタリングですでに通っている場合、このテストは RED ではなく、動作確認です。代わりに、新しい動作をテストしてください。

エッジケース

  • TDDをスキップする場合: 設定ファイル(.env、tsconfig.json)、静的コンテンツ、自動生成されたコード(Alembicマイグレーション)、一度限りのスクリプト、探索的なプロトタイピング。

  • 外部依存関係を伴うTDD: 境界でモック化します。外部APIを呼び出すサービスをテストする場合は、HTTPライブラリではなくAPIクライアントをモック化します。モックではなく、サービスの動作をテストします。

  • 大規模な機能: 機能を小さくテスト可能な動作に分割します。各動作に、それぞれ独自のRED-GREEN-REFACTORサイクルを適用します。すべてのサイクルを合わせて、機能全体を実装します。

  • テストのない既存コードのリファクタリング: まず既存の動作をテストするテスト(特性テスト)を書きます。次に、そのテストを安全網としてリファクタリングします。これは厳密なTDDではありませんが、テストファーストの考え方を活用する有効な方法です。

  • パターンスキルとの併用: このスキルでは、テストとコードをいつ書くかというWORKFLOWを定義します。テストをどのように構成するか、どのアサーションを使用するかというPATTERNSには、pytest-patternsまたはreact-testing-patternsを使用します。

コメント