关于 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 来做这个”或“先写测试”
- 构建验收标准明确的新功能
- 修复 Bug(先编写能复现 Bug 的测试,再修复)
- 为现有功能添加行为(先测试新行为)
- 用户希望在代码发布前证明其有效时
以下情况跳过 TDD: 简单的配置更改、没有逻辑的脚手架、文档。
如何使用
循环:Red -> Green -> Refactor
每项功能都要经历一个或多个 TDD 循环。一个循环涵盖一种独立行为。
步骤 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
如果重构期间有任何测试失败,请撤销上一次更改,然后尝试幅度更小的步骤。
多循环功能
大多数功能都需要多个 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
每个循环只添加一种行为。绝不要在单个循环中合并多种行为。
测试基础设施设置
如果项目缺少测试基础设施,请在第一个循环开始前完成设置:
- 创建包含 xUnit v3 和所需程序包的测试项目
- 配置
WebApplicationFactory,并使用 Testcontainers 连接真实数据库 - 添加共享 Fixture,避免每个测试类都启动容器
- 使用简单的健康检查测试验证基础设施
示例
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-- 生成由测试驱动的初始功能结构
评论
支持 Markdown