kasiopeiya

tdd

GitHub IssueからTDD(Test-Driven Development)サイクルを実行し、テストと実装を段階的に作成。アプリケーションコードの実装にTDDを適用する際に使用。

kasiopeiya 0 Updated 4w ago

Resources

1
GitHub

Install

npx skillscat add kasiopeiya/claude-dev-template/tdd

Install via the SkillsCat registry.

SKILL.md

指定されたGitHub Issueからアプリケーションコード(app/ 配下)のみを対象にTDDサイクル(Red-Green-Refactor)を実行してください。

Issue指定: $ARGUMENTS


TDD実行の詳細手順

GitHub Issueの内容を解析し、Red-Green-Refactorサイクルに従ってテストと実装を段階的に作成する。
本プロジェクトの仕様駆動開発フローにおける アプリ実装 工程を支援する。

スコープ制約

  • app/ 配下のみを対象とする
  • infra/ は変更しない(CDK は /cdk-imp の担当)
  • 新規ファイルを書き起こす前に samples/app/backend/ を Read する。 レイヤーの切り方・命名・テストの粒度の手本がある。samples/ 自体は変更しない
  • Issueのタスク一覧のうち、アプリケーションコードに関するタスクのみを実装対象とする
  • CDKスタック実装、Construct作成、インフラ設定、スナップショットテスト、cdk synth等は対象外
  • 対象外のタスクはスキップし、GitHub Issueのチェックリストも更新しないこと

実行プロセス

Phase 1: Issue読み込みと実装仕様の抽出

ステップ 1-1: Issue番号の取得

与えられた指示に Issue指定: に続く値が含まれていればそれを使う。含まれていなければ AskUserQuestion でIssue番号(例: 15)の入力を促す。

ステップ 1-2: GitHub IssueのJSON取得

Bash ツールで GitHub Issue の情報を取得:

gh issue view {番号} --json number,title,body,labels

Issue が見つからない場合・body が空の場合の扱いは references/error-handling.md に従う。

ステップ 1-3: Issue内容の解析

取得したJSONから以下を抽出する。

  • Issue番号:.number
  • タイトル:.title
  • ラベル:.labels[].name
  • スコープ/作業項目:body内 ## スコープ / 作業項目 セクションの内容全体
  • タスク一覧:body内 ## タスク一覧 のチェックリスト(- [ ] 形式)
  • 対象ファイル:body内 ## 📂 コンテキスト または ### 対象ファイル セクション
  • 実装詳細:body内 ### 実装詳細 セクション(存在する場合)

タスク一覧のフィルタリング(アプリケーションコードタスクのみを対象とする):

  • 対象:「Lambda実装」「ハンドラー実装」「API実装」「フロントエンド」「画面」「テストコード作成」「TDD」「単体テスト」等
  • 対象外(スキップ):「CDK」「cdk」「インフラ」「スタック」「Construct」「デプロイ」「synth」「スナップショット」等

キーワードだけで判断が難しい場合は、タスクの文脈からアプリケーションコード関連かどうかを判断する。フィルタリング結果(対象タスク・スキップしたタスク)は明示的に表示する。

ステップ 1-5: 対象ディレクトリの確認

app/ 配下を対象とする(ラベルによる分岐は行わない。ラベルの語彙・粒度はプロジェクトごとに異なりうるため)。

ステップ 1-6: テスト対象ファイルとテストファイルの特定

Issue内の「対象ファイル」セクションに実装ファイル・テストファイルのパスが明記されていればそのまま使う。記載がなければ AskUserQuestion で両方のパスを尋ねる。

ステップ 1-7: 実装仕様の整理と確認

抽出した情報を references/phase-reports.md の「実装仕様の確認」フォーマットで表示し、AskUserQuestion で開始可否を確認する。

  • 開始する:Phase 2へ
  • 修正する:ステップ 1-1へ戻る
  • 中断する:処理を中止

Phase 2: 赤フェーズ(Red)- 失敗するテストを作成

ステップ 2-0: テスト方針の読み込み(必須)

テストコードを書く前に、必ずテスト方針を定めるポリシーを Read ツールで読み込む。

ポリシーハブ docs/policy-hub.md を Read してテスト方針・テストダブル方針を定めるポリシー(例: unit-test-policy.md)を探し、Read で読み込む。書き方(AAA・命名・SUT・テストケースの分離・パラメータ化・フィクスチャ)は unit-test.md(Rule)を Read で読み込む。

読み込んだテスト方針から、以下のルールを抽出し、Phase 2〜Phase 7 の全工程で遵守する(該当箇所はポリシー文書の見出しから都度確認する。セクション番号は改訂で変わりうるためここでは固定しない):

  1. 振る舞いを検証し、実装の詳細を検証しない
  2. 検証手法の優先順位: 出力値ベース > 状態ベース > インタラクションベース
  3. 単体テストではモック・スタブを可能な限り使用しない(モックはポリシーが名指しする限定例外のみ可)
  4. スタブとのやりとりを検証してはならない
  5. AAAパターン(Arrange-Act-Assert)で構成する
  6. フェーズコメント(// Arrange 等)は準備 or 確認が複数行の場合のみ
  7. テストケース名は日本語、メソッド名を含めない、事実を示す表現
  8. SUT(テスト対象)を const sut = handler で明示する
  9. テスト内で if 文を使わない
  10. テストケースの分離は仕様上の条件で判断する
  11. パラメータ化テスト(it.each)は仕様上同じ条件のバリエーションに使用
  12. 正常系と異常系は必ず分離する
  13. beforeEach にテストケース固有データを置かない
  14. テストデータ共通化には Object Mother パターンを使用
  15. テスト対象はテスト方針ポリシーの一律ルールで決める(例外は名指しされたものだけ、自分で増やさない)
  16. フロントエンドはユーザーが認識できる属性で要素を取得(クエリの優先順位は react.md が定める)

さらに、設計ハブ docs/design-hub.md を Read し、Issueのラベル・タイトル・スコープと各設計書の担当範囲を照合して関連設計書(バックエンド仕様・フロントエンド仕様等)を特定・読み込み、テストケース設計の入力情報とする(特定ロジックは update-design スキルの Phase 2 に準じる)。

ステップ 2-1: テストケースの設計支援

グレーボックステストの考え方に基づき、スコープ/作業項目・実装詳細・設計書(インターフェース定義、シーケンス図、エラーハンドリング仕様)からテストケースを設計する。

設計の原則(ステップ 2-0 で読み込んだテスト方針に基づく):

  • テスト対象の一律ルール(対象/対象外/例外一覧)に照らして、テストすべきコードかを先に判断する。例外一覧に名指しされていないものを自分の判断で対象に加えてはならない
  • 仕様上の条件ごとにテストケースを分離する
  • 同じ条件のバリエーションは it.each でまとめる
  • 正常系と異常系は必ず分離する

設計結果を phase-reports.md の「テストケース設計の提示」フォーマットで表示し、AskUserQuestion で「推奨ケースで開始 / 追加する」を確認する。「追加する」なら追加したいテストケース(1行1ケース)を尋ねる。

ステップ 2-2: テストコードの生成

ステップ 2-0 で読み込んだテスト方針の全ルールに準拠したテストコードを生成する。書き方の具体例は references/code-examples.md のテストコード例(バックエンド/フロントエンド)を読む。

テストフレームワークの検出: Glob で package.json を検索し、Read で依存関係を確認する(jest → Jest形式、vitest → Vitest形式)。

ステップ 2-3: テスト方針準拠チェック

生成したテストコードを references/test-policy-checks.md の Phase 2 チェック項目すべてに照らして確認する。違反があれば、同ファイルの警告フォーマットで内容と対処方法を提示し、修正するか続行するかを確認する。

ステップ 2-4: テストファイルの作成/更新

新規なら Write でテストファイルを作成する。既存ファイルへの追加なら Read で読み込み、Edit で describe ブロックにテストケースを追加する。

ステップ 2-5: テストコードの確認

生成したテストコードを phase-reports.md の「作成したテストコードの提示」フォーマットで表示し、AskUserQuestion で「進める / 修正する」を確認する。

Phase 3: テスト実行(Red確認)

ステップ 3-1: unit-test スキル呼び出し

Skill ツールを使用して unit-test スキルを起動し、完了を待つ:

Skill({
  skill: 'unit-test',
  args: '{testFile} のテストを実行してください'
})

ステップ 3-2: テスト結果の解析

失敗の種別を見分ける。

  • 期待される失敗:Cannot find module './state'(実装が存在しない)、... is not a function(関数が未定義)
  • 予期しない失敗:SyntaxError: Unexpected token(構文エラー)、テスト側の Cannot find module(importパスエラー)

ステップ 3-3: 結果判定と報告

phase-reports.md の「Red Phase の結果報告」フォーマットで報告し、判定基準に従って遷移する。

  • 実装が存在しない/関数が未定義:Phase 4へ(AskUserQuestion で進行を確認)
  • 構文エラー/importエラー:Phase 2へ戻る(または中断)
  • テストが成功してしまった:警告を表示し Phase 2へ戻る

Phase 4: 緑フェーズ(Green)- 最小限の実装

ステップ 4-1: テストコードの解析

Phase 2で作成したテストコードから、関数名・引数の型と名前・戻り値の型・期待される動作を抽出する。抽出結果は phase-reports.md の「テストからの要件抽出」フォーマットで表示する。

ステップ 4-2: 最小限の実装コードの生成

原則:

  • テストを通す最小限のコードのみ
  • 過剰な実装や最適化は避ける
  • コメント・JSDoc は docs/policy/code-comment-policy.md に従う(実装コメントは WHY、doc comment は契約を書く。コードが語る WHAT/HOW は書かない)

書き方の具体例は code-examples.md の実装コード例を読む。

ステップ 4-3: TDD原則チェック

生成した実装コードを test-policy-checks.md の Phase 4 チェック項目に照らして確認する。違反があれば、同ファイルの警告フォーマットで内容と対処方法を提示し、修正するか続行するかを確認する。

ステップ 4-4: 実装ファイルの作成/更新

新規なら Write で実装ファイルを作成する。既存ファイルへの追加なら Read で読み込み、Edit で関数を追加する。

ステップ 4-5: 実装コードの確認

生成した実装コードを phase-reports.md の「生成した実装コードの提示」フォーマットで表示し、AskUserQuestion で「進める / 修正する」を確認する。

Phase 5: テスト実行(Green確認)

ステップ 5-1: unit-test スキル呼び出し

Skill ツールを使用して unit-test スキルを起動し、完了を待つ:

Skill({
  skill: 'unit-test',
  args: '{testFile} のテストを実行してください'
})

ステップ 5-2: テスト結果の解析

全テストが成功したか、どのテストがどの期待値で失敗したかを読み取る。

ステップ 5-3: 結果判定と報告

phase-reports.md の「Green Phase の結果報告」フォーマットで報告する。

  • ✅ 全テスト成功:AskUserQuestion で「Phase 6へ / Phase 4へ戻る / リファクタリングをスキップして Phase 7へ」を確認
  • ❌ 一部/全部失敗:Phase 4へ戻る(または中断)

Phase 6: リファクタリング(Refactor)

ステップ 6-1: リファクタリング可能性の分析

実装コード(重複排除、変数名改善、可読性向上)とテストコード(共通ロジック抽出、可読性向上)からリファクタリング候補を抽出する。

原則: 動作を変えない/テストが通ることを前提とする/過度な最適化は避ける(YAGNI原則)。

ステップ 6-2: リファクタリング提案の提示

候補を phase-reports.md の「リファクタリング提案」フォーマットで提示し、AskUserQuestion で「全て実行 / 選択 / スキップ」を確認する。「選択」なら各提案について個別に実行可否を尋ねる。

ステップ 6-3: リファクタリングの実行

Edit ツールでリファクタリングを実行する。テストコードのリファクタリング例は code-examples.md を読む。

ステップ 6-4: リファクタリング内容の確認

差分を表示し、AskUserQuestion で「Phase 7(最終確認)へ進む / さらにリファクタリングする」を確認する。

Phase 7: 最終確認(Final Verification)

ステップ 7-1: unit-test スキル呼び出し

Skill ツールを使用して unit-test スキルを起動し、完了を待つ:

Skill({
  skill: 'unit-test',
  args: '{testFile} のテストを実行してください'
})

ステップ 7-2: テスト結果の解析

期待される結果は全テスト成功(リファクタリング前と同じ)。失敗した場合はリファクタリングでバグが混入している。

ステップ 7-3: 結果判定

  • ✅ 全テスト成功:Phase 8へ
  • ❌ 失敗:phase-reports.md の「最終確認の失敗報告」フォーマットで報告し、AskUserQuestion で「ロールバック / 修正する / 中断する」を確認して Phase 6へ戻る

Phase 8: 設計書とのテスト整合性チェック(Design Verification)

ステップ 8-1: 関連設計書の読み込み

Phase 2(ステップ 2-0)で読み込んだテスト方針ポリシー・関連設計書を再度確認する。コンテキストが失われている場合は Read ツールで再読み込みする(テスト方針ポリシーは必ず対象、関連設計書はステップ2-0で特定したもの)。

抽出する情報:

  • インターフェース定義(関数シグネチャ、入出力の型、ステータスコード)
  • シーケンス図・フロー図(処理フロー、分岐条件、正常系・異常系パス)
  • エラーハンドリング仕様(エラーケース、エラーレスポンス)
  • ビジネスルール・制約条件
  • テスト方針ポリシーのテスト対象判断基準

ステップ 8-2: テストケースと設計書の照合

実装したテストファイルと実装コードを Read で読み込み、設計書から抽出した情報と照合する。

照合観点:

# 観点 確認内容
1 テストケースの網羅性 設計書に記載された正常系・異常系の処理パスがテストされているか
2 インターフェース整合性 テストで使用している入出力(引数の型、レスポンスの構造、ステータスコード等)が設計書のインターフェース定義と一致しているか
3 エラーケースの網羅性 設計書に記載されたエラーパターン(バリデーションエラー、認証エラー等)がテストされているか
4 テスト対象の妥当性 テスト方針ポリシーの基準に照らして、テスト対象が適切か(テスト不要なコードにテストを書いていないか)
5 テスト方針への準拠 テスト方針ポリシー(AAAパターン、命名規則、テストダブル方針、SUT明示、ブラックボックステスト等)に準拠しているか
6 テストレンズの指摘 テストレンズ(/code-review --lens テスト)が指摘したテストケースの不足がないか(実行手順は下記)

観点6は、Skill ツールで /code-review を起動して確認する:

Skill({
  skill: 'code-review',
  args: '--lens テスト {実装したファイルパス}'
})

照合ルール:

  • 設計書に明記されているがテストされていない:不足
  • テスト方針ポリシーで「テスト対象としないもの」に該当する:過剰
  • 設計書の型定義・ステータスコードとテストの期待値が不一致:不整合
  • テストレンズ(/code-review --lens テスト)が指摘した不足:不足(設計書に記載が無くても同じ)
  • 設計書にもテストレンズの指摘にも無いが、ビジネスロジック上テストすべき:推奨追加(強制はしない)

ステップ 8-3: チェック結果の報告

照合結果を phase-reports.md の「設計書とのテスト整合性チェック結果」フォーマットで報告し、AskUserQuestion で対応を確認する。

  • ✅ 問題なし:Phase 9へ進む / テストを追加する(Phase 2へ戻る)
  • ⚠️ 要対応:不足テストを追加(Phase 2へ戻り、Phase 2〜8を繰り返す) / 問題なしとして続行 / 中断する

Phase 9: 完了処理(Completion)

ステップ 9-1: GitHub Issueのタスクチェックリスト更新

Bash ツールで実装・テストに関連するタスクを完了マークに更新:

BODY=$(gh issue view {番号} --json body --jq '.body')
# 実装・テスト完了に関連するタスクを完了マークに更新
UPDATED_BODY=$(echo "$BODY" | sed 's/- \[ \] \(.*実装.*\)/- [x] \1/g' | sed 's/- \[ \] \(.*テスト.*\)/- [x] \1/g')
gh issue edit {番号} --body "$UPDATED_BODY"

該当するタスクが見つからない場合はスキップ(エラーにしない)。

ステップ 9-2: TDDサイクル完了レポート

phase-reports.md の「TDDサイクル完了レポート」フォーマットで完了を報告し、AskUserQuestion で「/tdd を再実行 / 終了」を確認する。

参照