Appearance
Metanaka .NET TDD
Overview
Kent Beck の Canon TDD を .NET backend 向けに運用する。 TDD は「テストを先に書くこと」だけではなく、テストリスト、ひとつだけの自動テスト、期待どおりの失敗確認、最小実装、green 後の refactor を繰り返す programming workflow として扱う。 このskillは規則の重要度を分類しない。Scopeの適用判定、Workflowの番号付き実行順序、Reportingの報告項目を必須として扱う。
Scope
対象。代表的な型と領域を示すが、pathではなくobservable production behaviorの変更かどうかで適用を判断する。
- Value Object、Entity、feature-local model、純粋な domain rule
- Handler と application service
- Request validator
- Repository interface など use case port の observable contract
- Minimal API endpoint の validation、status code、response body、error mapping
- Repository実装、provider mapping、外部service adapterのobservable behavior
- 共通API、validation、認証、runtime behavior
BackgroundService、IHostedService、scheduler、startup taskのobservable behavior
対象外:
- migration、generated artifact、単純な DTO 定義だけの追加
- wiring だけの DI registration、
Program.csの composition root だけの変更 - behavior を変えないproduction refactor(rename、format、内部整理、comment、document変更)
- production behaviorを変えないtest-only refactor、test organization変更、coverage追加
.csprojや tool 設定だけの変更
対象外でも、C# production codeに触れた場合は最後に関連するdotnet build、test codeに触れた場合は関連するdotnet testを実行して壊れていないことを確認する。両方に触れた場合は両方を実行する。 複合依頼で対象外のbehavior-preserving refactorをTDD対象変更より先に行う場合は、refactorに関連するtestのgreenを確認してからREDを開始し、後続REDの原因を分離する。要求されたbugを直接再現する既知のfailing testはこのcheckpointから除外し、既知のbaseline failureとして記録したうえで、次のREDとして単独実行する。作業末尾では、同じ範囲を満たすtestを重複実行しない。
Companion Skills
まず変更単位ごとにScopeを見て、このworkflowを適用する作業か判断する。複合依頼の一部が対象外なら、その変更にはRED/GREEN cycleを開始しない。
このTDDを適用する作業では、対象に応じて次のrepository skillも適用する。
metanaka-dotnet-coding: C#コード表現。metanaka-dotnet-architecture: 配置、依存方向、責務境界、またはHTTP/application/persistenceなど境界に属するcontractを設計、変更、レビューする場合のMinimal API、application、persistence、runtime。既存contract内の業務分岐だけを変更する場合は適用しない。metanaka-dotnet-testing: 完成するtest codeの構造と検証内容。
Workflow
小さな一巡の具体形が必要な場合だけsamples/value-object-cycle/README.mdを読み、RED、GREEN、REFACTORの差分を確認する。sampleの値や型名をproductionへそのまま移さない。
テストリストを作る。
- 期待する observable behavior を箇条書きで洗い出す。
- 実装方針、内部構造、抽象化案をテストリストに混ぜない。
- 既存動作を壊さないための回帰観点も入れる。
- ユーザーが要求したbehaviorと、その変更を安全に完了するために必要な回帰観点を今回の対象にする。調査中に見つけた別behaviorはfollow-upとして区別し、依頼範囲へ無断で追加しない。
- 業務語や validation rule が曖昧な場合は、テストリスト作成前に具体例を確認する。確認できない場合は既存仕様に合う最小の仮定を明記する。
次に書くテストをひとつだけ選ぶ。
- もっとも小さい observable behavior から始める。
- test file や test case を先に大量に書かない。
- 新しいtestを書く前に、同じbehaviorを直接検証する既存testがないか、対象production typeとbehavior名で検索する。
- テストを書く過程で public API の呼び出し方を設計してよい。実装設計は green 後まで遅らせる。
- 既存の失敗するtestが要求されたbugを直接再現している場合は、そのtestを次のtestとして選び、重複testを追加しない。
- 同じpublic behaviorへ同じ操作を行い、入力と期待値だけが異なる同値分割・境界値は、1つの
[Theory]と複数data rowを「ひとつの振る舞い」として選んでよい。 - error type、状態遷移、呼び出すcollaborator、永続化の有無など期待する観測結果が異なるcaseは、同じmethodを呼んでも別の振る舞いとして別cycleにする。
失敗する xUnit test を用意する。
- 既存testを選んだ場合は変更せず使い、新規testが必要な場合はtestを1つ書く。
- test codeは
metanaka-dotnet-testingに従う。 - 準備、操作、期待値の順に書く。
RED を確認する。
- まず対象 test case だけを実行する。
- filterは原則test methodに絞る。同じbehaviorを表すTheoryのdata rowや、method filterを安定して指定できない場合はtest classに絞る。
bash
dotnet test <test-project> --filter FullyQualifiedName~<Type>Tests.<MethodName>- 失敗理由が期待どおりであることを確認する。
- 作業開始時から失敗している既存testも、失敗理由が要求されたbugを直接示すならREDとして扱う。
- 期待どおり失敗したら、コンソールまたは作業ログに
🔴 RED: <失敗理由の要約>を表示する。 - pass した場合は既存動作をテストしているだけなので、テストリストに戻る。
- typo、誤ったnamespace、誤った既存APIの呼び出しなど、要求するbehaviorと無関係なcompile errorはtest側を直し、期待する失敗まで進める。
- 新しい型やmemberなど、これから追加するpublic APIがまだ存在しないためのcompile errorは、要求するbehaviorを直接示している場合に限り意図したREDとして扱う。失敗理由に欠けているAPIを明記し、次のGREENで最小のAPIとbehaviorを実装する。
- 意図したcompile REDと単純ミスを区別できない場合は、test listのbehaviorと照合する。behaviorを表すために必要な未実装APIなら前者、既存contractの読み違いなら後者とする。
最小実装で GREEN にする。
- いま失敗しているテストと、それまでのテストを通す最小変更だけを行う。
- 期待値を実行結果からコピーして貼り付けない。
- assertion を削って成功したことにしない。
- green にする途中で見つけた追加観点は、実装に混ぜずテストリストへ追加する。
GREEN を確認する。
- まず対象 test case を通す。
- 関連 unit test / integration test も必要に応じて実行する。
- 対象 test が通ったら、コンソールまたは作業ログに
🟢 GREEN: <通った確認の要約>を表示する。
必要なら refactor する。
- refactor は green の後だけ行う。
- 重複は抽象化の命令ではなくヒントとして扱う。
- 名前、責務、namespace、依存方向、test helper を整えたら、同じ test を再実行して green を保つ。
- refactor を行った場合は、コンソールまたは作業ログに
🟣 REFACTOR: <整理内容の要約>を表示する。
今回の対象にしたテストリストの未完了項目がなくなるまで繰り返す。
- ひとつの cycle につき、ひとつの振る舞いだけを扱う。
- Theoryを使う場合も、同じ規則の境界値をdata rowとして追加する範囲に留め、異なる業務分岐を1cycleへまとめない。
- follow-up項目は未実装のまま残してよい。最終報告で分けて示し、今回のproduction変更へ混ぜない。
- 作業の最後に対象 test project の
dotnet testと、該当する solution / project のdotnet buildを実行する。 - companion skillが同じbuildやtestを要求する場合は、この実行で共同充足し、同じ確認を重複実行しない。
- 既存 file の小さな変更では、今回の振る舞いに不要な file 移動、directory 再編、古い test style の全面修正を混ぜない。追加・変更した箇所だけを現行ルールへ寄せる。
Reporting
作業中は各cycleでRED / GREEN / REFACTORの該当markerを表示する。最終報告では、複数cycleの結果を次の項目へまとめてよい。
- 完了したテストリスト項目。
- 各REDで確認した失敗理由の1行要約。
- production変更とrefactorの要約。
- 実行した確認コマンドと結果。