tdd について
.NET 開発者向けのテスト駆動開発スキルです。失敗するテストの作成、最小限の実装、リファクタリングという Red-Green-Refactor の流れで、新機能や不具合修正を進めます。
主な機能
- 01動作ごとの TDD サイクル計画
- 02失敗するテストを先に作成・実行
- 03テストを通す最小限の実装
- 04テスト後のリファクタリング
- 05.NET テストツール群の利用
活用シーン
- 01受け入れ条件に沿った機能開発
- 02不具合を再現してから修正
- 03既存機能への動作追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ codewithmukesh/ dotnet-claude-kit --skill tddインストール後、Claude Code で/tddを入力して読み込まれたか確認します。
詳細
/tdd -- .NET 向け Red-Green-Refactor
概要
.NET の機能に対する厳格なテスト駆動開発サイクルをガイドします。まず実装を書き、後からテストを追加するのではなく、このコマンドでは順序を逆にします。望ましい動作を定義する失敗するテストを書き、それをパスさせるための最小限のコードを実装してから、自信を持ってリファクタリングします。
各サイクルでは .NET のテストスタックを使用します。
- xUnit v3 --
[Fact]と[Theory]を備えたテストフレームワーク - WebApplicationFactory -- 実際の HTTP パイプラインに対する統合テスト
- Testcontainers -- テストで実際のデータベース(PostgreSQL、SQL Server)を使用
- Verify -- 複雑なレスポンス構造のスナップショットテスト
- FakeTimeProvider -- テストにおける決定論的な時刻
使用するタイミング
- ユーザーが「TDD」「テスト駆動」「これを TDD で進めましょう」「最初にテストを書いて」と言った場合
- 明確な受け入れ基準がある新機能を構築する場合
- バグを修正する場合(最初にバグを再現するテストを書き、その後で修正します)
- 既存の機能に動作を追加する場合(最初に新しい動作のテストをします)
- コードのリリース前に、動作することを証明したいとユーザーが望む場合
TDD を省略する場合: 単純な設定変更、ロジックを含まないスキャフォールディング、ドキュメント。
手順
サイクル:Red -> Green -> Refactor
各機能は、1 つ以上の TDD サイクルで進めます。1 つのサイクルでは、個別の動作を 1 つ扱います。
ステップ 1:Red -- 失敗するテストを書く
望ましい動作を表すテストを書きます。実装がまだ存在しないため、テストは必ず失敗しなければなりません。
[Fact]
public async Task CreateOrder_WithValidItems_Returns201WithOrderId()
{
// Arrange
var client = _factory.CreateClient();
var request = new CreateOrderRequest([
new OrderItemRequest("SKU-001", 2, 29.99m)
]);
// Act
var response = await client.PostAsJsonAsync("/api/orders", request);
// Assert — plain xUnit Assert (FluentAssertions v8+ requires a commercial license)
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
var result = await response.Content.ReadFromJsonAsync<CreateOrderResponse>();
Assert.NotNull(result);
Assert.NotEqual(Guid.Empty, result.OrderId);
}
テストを実行し、失敗することを確認します。
dotnet test --filter "CreateOrder_WithValidItems_Returns201WithOrderId"
実装がないのにテストがパスする場合、そのテストは意図したものをテストできていません。書き直してください。
ステップ 2:Green -- 最小限の実装
テストをパスさせるための最小限のコードを書きます。機能、最適化、エッジケースへの対応は追加しないでください。目標はテストをパスさせることだけです。
- 必要に応じて、エンドポイント、ハンドラー、リクエスト/レスポンスの型、EF 設定を作成します
- テストのアサーションを満たす、最もシンプルなロジックを使用します
- まだリファクタリングはしません。この段階では、パスするコードが見苦しくても問題ありません
テストを実行し、パスすることを確認します。
dotnet test --filter "CreateOrder_WithValidItems_Returns201WithOrderId"
ステップ 3:Refactor -- 自信を持って整理する
テストがパスしたら、自由にリファクタリングします。
- メソッドの抽出、変数の名前変更、構造の改善
- 最新の C# パターン(プライマリコンストラクター、レコード、コレクション式)を適用
- バリデーション、エラー処理、エッジケースを追加(それぞれに新しいテストも追加)
- リファクタリングの各手順後にテストスイート全体を実行し、リグレッションを検出
dotnet test
リファクタリング中にテストが 1 つでも失敗したら、最後の変更を元に戻し、より小さな手順で試してください。
複数サイクルが必要な機能
ほとんどの機能では、複数の TDD サイクルが必要です。サイクルを事前に計画してください。
Feature: Order Management
Cycle 1: Create order with valid items -> 201
Cycle 2: Create order with empty items -> 400 validation error
Cycle 3: Create order with invalid SKU -> 400 with specific error
Cycle 4: Get order by ID -> 200 with full order details
Cycle 5: Get order that does not exist -> 404
各サイクルで動作を 1 つ追加します。1 つのサイクルで複数の動作を組み合わせてはいけません。
テストインフラストラクチャのセットアップ
プロジェクトにテストインフラストラクチャがない場合は、最初のサイクルの前にセットアップします。
- xUnit v3 と必要なパッケージを使ってテストプロジェクトを作成します
- 実際のデータベース用に、Testcontainers を使って
WebApplicationFactoryを設定します - テストクラスごとにコンテナーを起動せずに済むよう、共有フィクスチャを追加します
- 簡単なヘルスチェックテストでインフラストラクチャを検証します
例
User: /tdd Let's TDD a product search endpoint
Claude: I'll plan the TDD cycles for product search:
Cycle 1: Search with matching term returns matching products
Cycle 2: Search with no matches returns empty list
Cycle 3: Search with pagination returns correct page
Cycle 4: Search with filters narrows results
Starting Cycle 1: Red phase
Writing a failing integration test for basic product search...
[writes test, runs it, confirms failure]
Cycle 1: Green phase
Implementing the minimum to make the search test pass...
[implements, runs test, confirms pass]
Cycle 1: Refactor phase
The implementation works but the query could use a projection
instead of loading full entities. Refactoring...
[refactors, runs full suite, all green]
Cycle 1 complete. Moving to Cycle 2...
関連項目
/verify-- すべての TDD サイクル完了後に検証全体を実行します/scaffold-- テスト主導で進めるための初期機能構造を生成します