Skip to main content
ClaudeWave
Slash Command1.2k estrellas del repoactualizado 3mo ago

tdd

The tdd slash command invokes a tdd-guide agent that enforces Test-Driven Development methodology through a structured red-green-refactor cycle. It scaffolds interfaces, generates failing tests first, implements minimal code to pass tests, refactors while maintaining test passage, and verifies at least 80% code coverage. Use this command when implementing new features, adding functions or components, fixing bugs, refactoring existing code, or building critical business logic.

Instalar en Claude Code
Copiar
mkdir -p ~/.claude/commands && curl -fsSL https://raw.githubusercontent.com/xu-xiang/everything-claude-code-zh/HEAD/commands/tdd.md -o ~/.claude/commands/tdd.md
Después abre una sesión nueva de Claude Code; el slash command carga automáticamente.

tdd.md

# TDD 命令

此命令调用 **tdd-guide** 智能体(Agent)来强制执行测试驱动开发(Test-Driven Development, TDD)方法论。

## 此命令的作用

1. **搭建接口脚手架(Scaffold Interfaces)** - 首先定义类型/接口
2. **先生成测试(Generate Tests First)** - 编写失败的测试(红色 - RED)
3. **实现最少代码(Implement Minimal Code)** - 编写刚好能通过测试的代码(绿色 - GREEN)
4. **重构(Refactor)** - 在保持测试通过的同时改进代码(重构 - REFACTOR)
5. **验证覆盖率(Verify Coverage)** - 确保 80% 以上的测试覆盖率(Coverage)

## 何时使用

在以下情况下使用 `/tdd`:
- 实现新功能
- 添加新的函数/组件
- 修复 Bug(先编写能复现 Bug 的测试)
- 重构现有代码
- 构建关键业务逻辑

## 工作原理

tdd-guide 智能体会执行以下操作:

1. 为输入/输出**定义接口(Interfaces)**
2. **编写将要失败(FAIL)的测试**(因为代码尚不存在)
3. **运行测试**并验证它们因正确的理由而失败
4. **编写最少量的实现代码**使测试通过
5. **运行测试**并验证它们已通过
6. 在保持测试通过的同时**重构(Refactor)**代码
7. **检查覆盖率(Coverage)**,如果低于 80% 则添加更多测试

## TDD 循环

```
红色 (RED) → 绿色 (GREEN) → 重构 (REFACTOR) → 重复 (REPEAT)

红色 (RED):      编写一个失败的测试
绿色 (GREEN):    编写最少代码以通过测试
重构 (REFACTOR): 改进代码,保持测试通过
重复 (REPEAT):   下一个功能/场景
```

## 使用示例

```
用户: /tdd 我需要一个计算市场流动性评分的函数

智能体 (tdd-guide):
# TDD 会话:市场流动性评分计算器

## 步骤 1:定义接口 (SCAFFOLD)

```typescript
// lib/liquidity.ts
export interface MarketData {
  totalVolume: number
  bidAskSpread: number
  activeTraders: number
  lastTradeTime: Date
}

export function calculateLiquidityScore(market: MarketData): number {
  // TODO: 实现
  throw new Error('Not implemented')
}
```

## 步骤 2:编写失败的测试 (RED)

```typescript
// lib/liquidity.test.ts
import { calculateLiquidityScore } from './liquidity'

describe('calculateLiquidityScore', () => {
  it('should return high score for liquid market', () => {
    const market = {
      totalVolume: 100000,
      bidAskSpread: 0.01,
      activeTraders: 500,
      lastTradeTime: new Date()
    }

    const score = calculateLiquidityScore(market)

    expect(score).toBeGreaterThan(80)
    expect(score).toBeLessThanOrEqual(100)
  })

  it('should return low score for illiquid market', () => {
    const market = {
      totalVolume: 100,
      bidAskSpread: 0.5,
      activeTraders: 2,
      lastTradeTime: new Date(Date.now() - 86400000) // 1 day ago
    }

    const score = calculateLiquidityScore(market)

    expect(score).toBeLessThan(30)
    expect(score).toBeGreaterThanOrEqual(0)
  })

  it('should handle edge case: zero volume', () => {
    const market = {
      totalVolume: 0,
      bidAskSpread: 0,
      activeTraders: 0,
      lastTradeTime: new Date()
    }

    const score = calculateLiquidityScore(market)

    expect(score).toBe(0)
  })
})
```

## 步骤 3:运行测试 - 验证失败 (FAIL)

```bash
npm test lib/liquidity.test.ts

FAIL lib/liquidity.test.ts
  ✕ should return high score for liquid market (2 ms)
    Error: Not implemented

1 test failed, 0 passed
```

✅ 测试如预期般失败。准备开始实现。

## 步骤 4:实现最少代码 (GREEN)

```typescript
// lib/liquidity.ts
export function calculateLiquidityScore(market: MarketData): number {
  // 处理零交易量的边缘情况
  if (market.totalVolume === 0) {
    return 0
  }

  // 计算各部分得分 (0-100 比例)
  const volumeScore = Math.min(market.totalVolume / 1000, 100)
  const spreadScore = Math.max(100 - (market.bidAskSpread * 1000), 0)
  const traderScore = Math.min(market.activeTraders / 10, 100)

  // 最近活动奖励
  const hoursSinceLastTrade = (Date.now() - market.lastTradeTime.getTime()) / (1000 * 60 * 60)
  const recencyScore = Math.max(100 - (hoursSinceLastTrade * 10), 0)

  // 加权平均
  const score = (
    volumeScore * 0.4 +
    spreadScore * 0.3 +
    traderScore * 0.2 +
    recencyScore * 0.1
  )

  return Math.min(Math.max(score, 0), 100) // 限制在 0-100
}
```

## 步骤 5:运行测试 - 验证通过 (PASS)

```bash
npm test lib/liquidity.test.ts

PASS lib/liquidity.test.ts
  ✓ should return high score for liquid market (3 ms)
  ✓ should return low score for illiquid market (2 ms)
  ✓ should handle edge case: zero volume (1 ms)

3 tests passed
```

✅ 所有测试均已通过!

## 步骤 6:重构 (IMPROVE)

```typescript
// lib/liquidity.ts - 使用常量重构,提高可读性
const WEIGHTS = {
  VOLUME: 0.4,
  SPREAD: 0.3,
  TRADERS: 0.2,
  RECENCY: 0.1,
} as const

const SCALE_FACTORS = {
  VOLUME: 1000,
  SPREAD: 1000,
  TRADERS: 10,
  RECENCY_PENALTY: 10,
} as const

function clamp(value: number, min: number, max: number): number {
  return Math.min(Math.max(value, min), max)
}

export function calculateLiquidityScore(market: MarketData): number {
  if (market.totalVolume === 0) return 0

  const volumeScore = Math.min(market.totalVolume / SCALE_FACTORS.VOLUME, 100)
  const spreadScore = clamp(100 - (market.bidAskSpread * SCALE_FACTORS.SPREAD), 0, 100)
  const traderScore = Math.min(market.activeTraders / SCALE_FACTORS.TRADERS, 100)

  const hoursSinceLastTrade = (Date.now() - market.lastTradeTime.getTime()) / (1000 * 60 * 60)
  const recencyScore = clamp(100 - (hoursSinceLastTrade * SCALE_FACTORS.RECENCY_PENALTY), 0, 100)

  const weightedScore =
    volumeScore * WEIGHTS.VOLUME +
    spreadScore * WEIGHTS.SPREAD +
    traderScore * WEIGHTS.TRADERS +
    recencyScore * WEIGHTS.RECENCY

  return clamp(weightedScore, 0, 100)
}
```

## 步骤 7:验证测试依然通过

```bash
npm test lib/liquidity.test.ts

PASS lib/liquidity.test.ts
  ✓ should return high score for liquid market (3 ms)
  ✓ should return low score for illiquid market (2 ms)
  ✓ should handle edge case: zero volume (1 ms)

3 tests passed
```

✅ 重构完成,测试依然通过!

## 步骤 8:检查覆盖率 (Coverage)

```bash
npm test -- --coverage lib/liquidity.test.ts

File           | % Stmts | % Branch | % Funcs | % Lines
---------------|---------|----------|---------|--------
liquidity.ts   |   100   |   100    |   100   |   100

Coverage: 100% ✅ (目标: 80%)
```

✅ TDD 会话完成!
```

## TDD 最佳实践

**建议 (DO):**
- ✅ 在进行任何实现之前,**首先**编写测试
- ✅ 在实现之前,运行测试并验证它们**失败 (FAIL)**
- ✅ 编写最少量的代码以通过测试
- ✅ 仅在测试变绿(通过)后才进行重构
- ✅ 添加边缘情况(Edge cases)和错误场景
- ✅ 目标是 80% 以上的覆盖率(关键代码为 100%)

**禁止 (DON'T):**
- ❌ 在测试之前编写实现代码
- ❌ 跳过每次更改后的测试运行
- ❌ 一次编写过多代码
- ❌ 忽略失败的测试
- ❌ 测试实现细节(应测试行为)
- ❌ 模拟(Mock)一切(优先考虑集成测试)

## 应包含的测试类型

**单元测试 (Unit Tests)**(函数级):
- 正常路径场景
- 边缘情况(空值、null、最大值)
- 错误条件
- 边界值

**集成测试 (Integration Tests)**(组件级):
- API 终端节点
- 数据库操作
- 外部服务调用
- 带有 Hook 的 React 组件

**端到端测试 (E2E Tests)**(使用 `/e2e` 命令):
- 关键用户流程
- 多步骤过程
- 全栈集成

## 覆盖率要求

- 所有代码**最低 80%**
- 以下内容**要求 10
api-designSkill

生产级 API 的 REST API 设计模式,包括资源命名、状态码、分页、过滤、错误响应、版本控制和速率限制。

article-writingSkill

编写文章、指南、博客、教程、时事通讯(Newsletter)等长内容,支持从示例或品牌指南中提取独特的语感语调。适用于需要撰写超过一个段落的精炼文本,尤其是对语气一致性、结构和可信度有较高要求时。

backend-patternsSkill

后端架构模式、API 设计、数据库优化以及 Node.js、Express 和 Next.js API 路由的服务端最佳实践。

coding-standardsSkill

TypeScript、JavaScript、React、Node.js 开发的通用编码标准、最佳实践和模式。

content-engineSkill

为 X、LinkedIn、TikTok、YouTube、时事通讯(Newsletters)以及跨平台内容重加工营销活动(Repurposed multi-platform campaigns)创建平台原生的内容系统。当用户需要社交媒体帖子、推文串(Threads)、脚本、内容日历,或将单一源素材清晰地适配到多个平台时使用。

e2e-testingSkill

Playwright E2E 测试模式、页面对象模型(POM)、配置、CI/CD 集成、产物管理以及不稳定测试(flaky test)策略。

eval-harnessSkill

适用于 Claude Code 会话的正规评测框架(Evaluation Framework),实现了评测驱动开发(Eval-Driven Development, EDD)原则

frontend-patternsSkill

React、Next.js、状态管理(State Management)、性能优化(Performance Optimization)及 UI 最佳实践的前端开发模式。