Appearance
Metanaka Nuxt TDD Workflow
Overview
Kent Beck の Canon TDD を、この Nuxt repository の composable と utility 向けに運用する。 TDD は「テストを先に書くこと」だけではなく、テストリスト、ひとつだけの自動テスト、期待通りの失敗確認、最小実装、green 後の refactor を繰り返す programming workflow として扱う。
Scope
対象:
apps/nuxt/app/features/**/use-*.tsapps/nuxt/app/features/**/*.tsの utility、adapter、model 寄りの振る舞いapps/nuxt/app/shared/**/use-*.tsapps/nuxt/app/shared/**/*.tsの utility、adapter、model 寄りの振る舞い- 対象 file と同じ slice に置く
*.test.ts
対象外:
.vueコンポーネント本体の UI/DOM/アクセシビリティ変更- Playwright E2E の主対象になる画面操作フロー
- 生成物、単純な文書変更、振る舞いを変えない設定変更
.vue に振る舞いがある場合は、先に composable、model、utility へ切り出してからこの workflow を適用する。Vue file は表示、props/emits、軽い computed、event handler から composable へ委譲する程度に保つ。
Required Companion Rules
まず Scope を見て、この workflow を適用する作業か判断する。対象外なら RED/GREEN cycle を開始せず、次の companion rules も追加で読まない。
この workflow を適用する作業では、次の repository skill も適用する。
metanaka-vitest-rule: unit test のタイトル、構造、mock 方針。metanaka-nuxt-style-rule: feature/shared の配置と命名。metanaka-typescript-style-rule: const、arrow function、純粋関数中心の TypeScript style。metanaka-nuxt-i18n-rule: i18n key、validation message key、locale source を追加・変更・移動する場合だけ追加で適用する。既存 key を読むだけなら不要。
Workflow
テストリストを作る。
- 期待する振る舞いを箇条書きで洗い出す。
- 実装方針、内部構造、抽象化案をテストリストに混ぜない。
- 既存動作を壊さないための回帰観点も入れる。
- 「正規化」「有効な入力」のような仕様語が曖昧な場合は、テストリスト作成前に具体例を確認する。確認できない場合は既存仕様に合う最小の仮定を明記する。
次に書くテストをひとつだけ選ぶ。
- もっとも小さい observable behavior から始める。
- テストコードを先に大量に書かない。
- テストを書く過程で API の呼び出し方を設計してよい。実装設計は green 後まで遅らせる。
失敗する Vitest を書く。
- 対象 file と同じ directory に
*.test.tsを置く。 - テストタイトルは日本語で、前提または操作と期待値が分かる形にする。
- 既存 test file に英語 title や古い書き方が残っていても、今回追加・変更する test title と assertion を現行ルールに合わせる。無関係な既存 test の一括修正はしない。
- 準備、操作、期待値の順に書く。
- assertion のないテストや snapshot だけで意図が読めないテストは書かない。
- 対象 file と同じ directory に
RED を確認する。
pnpm test:unit -- <path/to/test.test.ts>を基本に、対象テストだけを実行する。- 失敗理由が期待どおりであることを確認する。
- 期待どおり失敗したら、コンソールまたは作業ログに
🔴 RED: <失敗理由の要約>を表示する。 - pass した場合は既存動作をテストしているだけなので、テストリストに戻る。
- 新規テストが既存実装ですでに pass した場合は、未実装の observable behavior を選び直す。要求内に未実装 behavior が残っていなければ RED/GREEN を進めず、「既存実装で満たされている」と報告して終了する。
- syntax error、import error、型の単純ミスなら、期待する失敗になるまでテスト側を直して再実行する。
最小実装で GREEN にする。
- いま失敗しているテストと、それまでのテストを通す最小変更だけを行う。
- 期待値を実行結果からコピーして貼り付けない。
- assertion を削って成功したことにしない。
- green にする途中で見つけた追加観点は、実装に混ぜずテストリストへ追加する。
GREEN を確認する。
- まず対象テストを通す。
- 関連 unit test も必要に応じて実行する。
- TypeScript 実装または test code に触れた場合は
pnpm tcも実行する。特に composable の戻り値、Firestore 保存型、i18n key、route params/query、テストコード型に触れた場合は省略しない。 - 対象テストが通ったら、コンソールまたは作業ログに
🟢 GREEN: <通った確認の要約>を表示する。
必要なら refactor する。
- refactor は green の後だけ行う。
- 重複は抽象化の命令ではなくヒントとして扱う。
- 名前、責務、境界を整えたら、同じテストを再実行して green を保つ。
- refactor を行った場合は、コンソールまたは作業ログに
🟣 REFACTOR: <整理内容の要約>を表示する。
テストリストが空になるまで繰り返す。
- ひとつの cycle につき、ひとつの振る舞いだけを扱う。
- 作業の最後に
pnpm test:unitと、該当する場合はpnpm tcを実行する。 - 既存 file や既存 slice の小さな変更では、今回の振る舞いに不要な file 移動、directory 再編、古い test style の全面修正を混ぜない。追加・変更した箇所だけを現行ルールへ寄せる。
Placement
feature code:
text
apps/nuxt/app/features/<feature>/
use-thing.ts
use-thing.test.ts
thing-model.ts
thing-model.test.ts
feature-local-utility.ts
feature-local-utility.test.tsshared code:
text
apps/nuxt/app/shared/<concept>/
use-thing.ts
use-thing.test.ts
resolve-thing.ts
resolve-thing.test.ts
model.ts
model.test.ts新規 shared code は app/shared/utils/ のような役割別 directory ではなく、共有概念ごとの slice を優先する。既存の app/shared/utils/ にある対象を小さく修正する場合は、不要な移動を避けて近傍に合わせる。
Test Design
- composable は返り値、ref の状態変化、公開関数の結果、外部境界の呼び出しを検証する。
- utility/model は入力と出力、状態遷移、validation result、error key、境界条件を検証する。
- Firestore、Firebase Auth、timer、random、現在時刻、browser API は外部境界として扱う。
- 新規 code では外部境界を小さな引数や thin wrapper に寄せ、module mock を常用しない。
- 既存 code の分離が大きすぎる場合は、最小限の module mock を許容する。
- i18n 対象データや共有状態では表示文字列ではなく key を扱うことを確認する。
Reporting
作業中または最終報告では、TDD の各 cycle について最低限次を伝える。
- 選んだテストリスト項目。
🔴 RED: ...で確認した失敗理由。- GREEN のために入れた最小実装。
🟢 GREEN: ...で通した確認内容。🟣 REFACTOR: ...で整理した内容。refactor しなかった場合は不要。- 実行した確認コマンド。