Skip to content

Metanaka Nuxt TDD Workflow

Overview

Kent Beck の Canon TDD を、この Nuxt repository の composable と utility 向けに運用する。 TDD は「テストを先に書くこと」だけではなく、テストリスト、ひとつだけの自動テスト、期待通りの失敗確認、最小実装、green 後の refactor を繰り返す programming workflow として扱う。

Scope

対象:

  • apps/nuxt/app/features/**/use-*.ts
  • apps/nuxt/app/features/**/*.ts の utility、adapter、model 寄りの振る舞い
  • apps/nuxt/app/shared/**/use-*.ts
  • apps/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

  1. テストリストを作る。

    • 期待する振る舞いを箇条書きで洗い出す。
    • 実装方針、内部構造、抽象化案をテストリストに混ぜない。
    • 既存動作を壊さないための回帰観点も入れる。
    • 「正規化」「有効な入力」のような仕様語が曖昧な場合は、テストリスト作成前に具体例を確認する。確認できない場合は既存仕様に合う最小の仮定を明記する。
  2. 次に書くテストをひとつだけ選ぶ。

    • もっとも小さい observable behavior から始める。
    • テストコードを先に大量に書かない。
    • テストを書く過程で API の呼び出し方を設計してよい。実装設計は green 後まで遅らせる。
  3. 失敗する Vitest を書く。

    • 対象 file と同じ directory に *.test.ts を置く。
    • テストタイトルは日本語で、前提または操作と期待値が分かる形にする。
    • 既存 test file に英語 title や古い書き方が残っていても、今回追加・変更する test title と assertion を現行ルールに合わせる。無関係な既存 test の一括修正はしない。
    • 準備、操作、期待値の順に書く。
    • assertion のないテストや snapshot だけで意図が読めないテストは書かない。
  4. RED を確認する。

    • pnpm test:unit -- <path/to/test.test.ts> を基本に、対象テストだけを実行する。
    • 失敗理由が期待どおりであることを確認する。
    • 期待どおり失敗したら、コンソールまたは作業ログに 🔴 RED: <失敗理由の要約> を表示する。
    • pass した場合は既存動作をテストしているだけなので、テストリストに戻る。
    • 新規テストが既存実装ですでに pass した場合は、未実装の observable behavior を選び直す。要求内に未実装 behavior が残っていなければ RED/GREEN を進めず、「既存実装で満たされている」と報告して終了する。
    • syntax error、import error、型の単純ミスなら、期待する失敗になるまでテスト側を直して再実行する。
  5. 最小実装で GREEN にする。

    • いま失敗しているテストと、それまでのテストを通す最小変更だけを行う。
    • 期待値を実行結果からコピーして貼り付けない。
    • assertion を削って成功したことにしない。
    • green にする途中で見つけた追加観点は、実装に混ぜずテストリストへ追加する。
  6. GREEN を確認する。

    • まず対象テストを通す。
    • 関連 unit test も必要に応じて実行する。
    • TypeScript 実装または test code に触れた場合は pnpm tc も実行する。特に composable の戻り値、Firestore 保存型、i18n key、route params/query、テストコード型に触れた場合は省略しない。
    • 対象テストが通ったら、コンソールまたは作業ログに 🟢 GREEN: <通った確認の要約> を表示する。
  7. 必要なら refactor する。

    • refactor は green の後だけ行う。
    • 重複は抽象化の命令ではなくヒントとして扱う。
    • 名前、責務、境界を整えたら、同じテストを再実行して green を保つ。
    • refactor を行った場合は、コンソールまたは作業ログに 🟣 REFACTOR: <整理内容の要約> を表示する。
  8. テストリストが空になるまで繰り返す。

    • ひとつの 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.ts

shared 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 しなかった場合は不要。
  • 実行した確認コマンド。