tdd-workflow について
複数の言語やテストフレームワークに対応する TDD ワークフローのスキルです。失敗するテスト、最小限の実装、リファクタリング、完了確認を順に進め、任意でタスク追跡も行います。
主な機能
- 01Red-Green-Refactor サイクル
- 02言語とテストランナーの検出
- 03段階的なテスト計画
- 04一時停止と続行のルール
- 05テスト品質と順序の指針
- 06任意のタスク追跡連携
活用シーン
- 01テスト済みの小さな単位で機能を開発
- 02テストが想定した理由で失敗するか確認
- 03回帰を確認しながらリファクタリング
- 04既存コードのテスト範囲を計画
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill tdd-workflowインストール後、Claude Code で/tdd-workflowを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/increments.mdlanguage-configs.mdrails-tdd-workflow.md詳細
TDD ワークフロー
基本原則
その動作に対する失敗するテストが存在する前に、実装コードを書いてはいけません。
実行フロー
1. セットアップ
LANG = config_read("tech_stack", "unknown")
If LANG == "unknown": detect from project files (package.json → TypeScript, Gemfile → Ruby, go.mod → Go, pyproject.toml → Python)
If LANG == "unknown": AskUserQuestion("What language/framework?")
RUNNER = lookup LANG in [references/language-configs.md]
If LANG in [ruby]: delegate to `rspec-coder` or `minitest-coder` skill for runner details
INCREMENTS = decompose feature using patterns from [references/increments.md]
- Read requirements/plan
- Identify pattern (Data Transformation, CRUD, State Machine, Calculation, Integration)
- Break into ordered increments: degenerate → happy path → variations → edge cases → errors
For each INCREMENT in INCREMENTS:
TaskCreate(subject: INCREMENT.name, description: INCREMENT.test_description)
AskUserQuestion("Review increments. Adjust ordering or scope?", options: ["Looks good", "Modify"])
2. TDD ループ(増分ごと)
For each INCREMENT in INCREMENTS:
TaskUpdate(INCREMENT.task_id, status: "in_progress")
# RED
Write failing test to real file (not code block)
RUN = Bash(RUNNER.test_command)
If RUN.status == PASS: STOP — investigate unexpected pass
If RUN.status == FAIL (wrong reason): fix test, rerun
PAUSE → show test + failure output, wait for user
# GREEN
Write minimal implementation code
RUN = Bash(RUNNER.full_suite_command)
If RUN.status == FAIL: show output, PAUSE → ask user to fix or hand off
If RUN.status == PASS: auto-continue (no pause)
# REFACTOR
If improvement opportunities exist:
Refactor implementation and/or test code
RUN = Bash(RUNNER.full_suite_command)
If RUN.status == FAIL: revert refactor, PAUSE → discuss
If RUN.status == PASS: auto-continue (no pause)
TaskUpdate(INCREMENT.task_id, status: "completed")
Brief summary of what was implemented
→ immediately begin next increment (no pause between increments)
3. まとめ
RUN = Bash(RUNNER.full_suite_command)
Report: increments completed, total tests, pass/fail status
Suggest: remaining work, missed edge cases, integration tests needed
一時停止/続行ルール
| 状況 | アクション |
|---|---|
| RED:テストが失敗する(想定どおり) | 一時停止 — テストと失敗内容を示し、ユーザーを待つ |
| RED:テストが予期せず成功する | 停止 — 調査し、続行しない |
| GREEN:すべてのテストが成功する | 自動続行して REFACTOR へ |
| GREEN:テストが失敗する | 一時停止 — 出力を示し、ユーザーに確認する |
| REFACTOR:テストが成功する | 自動続行して次の増分へ |
| REFACTOR:テストが失敗する | 元に戻して一時停止 — アプローチを話し合う |
| 増分の間 | 自動続行 — 一時停止しない |
タスク追跡との連携
TASK_TRACKING = config_read("task_tracking.enabled", "false")
WORKFLOW_ID = "tdd-{timestamp}"
If TASK_TRACKING:
For each TaskCreate: add metadata {workflow: WORKFLOW_ID, phase: "tdd-loop"}
For each TaskUpdate: wrap with If TASK_TRACKING: TaskUpdate(...)
On Wrap-up: update ledger if LEDGER_ENABLED
LEDGER_ENABLED = config_read("task_tracking.ledger", "false")
LEDGER_PATH = config_read("task_tracking.ledger_path", ".agents/workflow-ledger.yml")
Red-Green-Refactor サイクル
1. Red フェーズ:失敗するテストを書く
- 増分から、小さく具体的な動作を1つ選びます
- 期待する動作を表す、内容の分かりやすいテストを書きます
- テストを実行し、失敗することを確認します(red)
- 適切な理由で失敗している必要があります(構文エラーや依存関係の不足ではありません)
2. Green フェーズ:最小限の実装
- 失敗するテストを通すために必要な最小限のコードだけを実装します
- テストでまだカバーされていない追加機能やエッジケースへの対応を加えないようにします
- テストを実行し、成功することを確認します(green)
3. Refactor フェーズ:品質を向上させる
- 実装コードとテストコードの両方を見直し、改善点を探します
- 重複をなくし、命名を改善し、メソッドを抽出します
- 言語固有の慣用表現やパターンを適用します
- リファクタリングの各ステップ後にテストを実行し、引き続き成功することを確認します
テストの順序付け方針
テストは簡単なものから複雑なものへと並べます。
- 正常系 — 有効な入力に対する基本動作
- バリデーションテスト — 必須フィールド、形式の制約
- エッジケース — 境界条件、空の値、通常とは異なる入力
- エラーハンドリング — 無効な入力、失敗のシナリオ
- 統合ポイント — 他のコンポーネントとのやり取り
テスト品質のガイドライン
各テストは、次の条件を満たす必要があります。
- 1つの動作だけを対象にする
- 分離されている — テスト間で状態を共有しない
- 明確で説明的な名前を持つ
- 失敗する理由が1つだけである
避けること:
- 動作ではなく実装の詳細をテストする
- コードを書いた後にテストを書く
- 隠れた依存関係を生むテストセットアップを共有する
- リファクタリングのフェーズを省略する
フレームワーク固有の実装
言語固有のテストランナーコマンドについては、references/language-configs.md を参照してください。
Ruby プロジェクトの場合:
- RSpec:
rspec-coderスキルを適用します - Minitest:
minitest-coderスキルを適用します
Rails の例は、references/rails-tdd-workflow.md で確認できます。
テスト生成パターン
TDD ループの外でテストを書く場合(例:既存コードにカバレッジを追加する場合)は、次のパターンに従ってください。
フレームワークの検出
| 手掛かり | フレームワーク |
|---|---|
spec/ + _spec.rb + .rspec | RSpec |
test/ + _test.rb + test_helper.rb | Minitest |
*.test.js + jest.config.js | Jest |
tests/ または e2e/ 内の *.spec.ts | Playwright |
vitest.config.js | Vitest |
テスト計画の構成
テストを書く前に、次の項目を含む計画を作成します。
- 対象範囲 - テストする機能
- 正常系のシナリオ - 期待される成功フロー
- 異常系のシナリオ - エラーハンドリング、バリデーション、失敗
- エッジケース - 境界条件、null/空の値、通常とは異なる入力
- 認証チェック - 認可/認証(該当する場合)
- テストデータの要件 - 必要なフィクスチャまたはデータ
- モック戦略 - モックする外部サービス/依存関係
テストケースマトリックス
複数のパラメーターを含む複雑なシナリオで使用します。
| 目的 | 入力 | 期待される出力 | テストの種類 |
|---|---|---|---|
| 作成を検証する | 有効なパラメーター | 作成済み、201 | 正常系 |
| 重複を拒否する | 既存のデータ | エラー、422 | 異常系 |
| 空の場合を処理する | フィールドが不足 | 検証エラー | 境界ケース |
完了基準
以下のすべてを満たしたら、テストは完了です。
カバレッジ: すべての公開メソッドをテストし、正常系・異常系・境界ケースをカバーし、認証チェックを含めます。
品質: テストが合格し(実行して確認済み)、独立していて(状態を共有せず)、AAA パターン(Arrange-Act-Assert)に従い、名前が分かりやすいこと。
フレームワークへの準拠: 適切なマッチャーを使い、適切にモックし、プロジェクトのパターンに従っていること。
テスト作成のベストプラクティス
- 実装の詳細ではなく、振る舞いをテストする
- 1 つのテストにつき、アサーションの焦点を 1 つにする
- 期待する振る舞いが分かる、説明的なテスト名を付ける
- 暗黙的なアサーションより、明示的なアサーションを優先する
- テストダブルは必要最小限に、目的を明確にして使用する
- 関連するテストを describe/context ブロックでグループ化する
- テストデータは必要最小限にする
- Rails の場合:トランザクショナルフィクスチャとデータベースクリーナーを使用する
- Playwright の場合:適切な待機戦略を使い、不安定なセレクターを避ける
コメント
Markdown 対応