Commonly-used-high-value-skills test-driven-development

用于 TDD 红绿重构循环、测试策略制定和测试反模式规避。来源:obra/superpowers。

install
source · Clone the upstream repo
git clone https://github.com/seaworld008/Commonly-used-high-value-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/seaworld008/Commonly-used-high-value-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/openclaw-skills/test-driven-development" ~/.claude/skills/seaworld008-commonly-used-high-value-skills-test-driven-development && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/seaworld008/Commonly-used-high-value-skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/openclaw-skills/test-driven-development" ~/.openclaw/skills/seaworld008-commonly-used-high-value-skills-test-driven-development && rm -rf "$T"
manifest: openclaw-skills/test-driven-development/SKILL.md
source content

Test-Driven Development (TDD)

TDD is a disciplined engineering practice where tests are written before the code itself. It isn't just about testing; it's about design and confidence. This skill teaches the "Red-Green-Refactor" cycle and professional testing strategy.

触发条件

  • 正在编写具有复杂业务逻辑、边界情况多、且需要长期维护的核心算法。
  • 需要在一个庞大且容易产生副作用的单体架构中增加新功能。
  • 团队对代码重构感到恐惧,因为没有测试保护。
  • 追求高代码质量、低缺陷率和更清晰的代码设计。
  • 需要在敏捷开发中实现持续交付(Continuous Delivery)。

核心能力

1. RED-GREEN-REFACTOR 严格循环

  • Phase 1: RED (Fail): 编写一个尽可能简单的、描述业务意图的测试用例。此时代码尚未实现,测试必须失败。
  • Phase 2: GREEN (Pass): 编写最少、最简单的代码,让测试通过。不要考虑优雅和通用,只要能跑过。
  • Phase 3: REFACTOR (Improve): 在测试保护下重构代码。消除重复,优化命名,提高可读性,确保逻辑清晰。测试必须保持通过。

2. 测试金字塔 (Testing Pyramid)

  • Unit Tests (Bottom): 数量最多。隔离测试单一类或函数。极速运行。
  • Integration Tests (Middle): 测试多个组件或模块的协同工作(如 DB 交互、API 调用)。
  • E2E Tests (Top): 模拟用户真实路径。数量最少。最慢且最容易因为环境变化而失败。

3. Mock vs Stub vs Spy

  • Dummy: 仅用于填充参数列表的对象。
  • Stub: 为测试提供预定义好的返回值(Fixed data)。
  • Mock: 关注交互验证(验证某个方法是否被调用、调用了几次)。
  • Spy: 包装真实对象,既保留真实逻辑又记录调用信息。

4. 测试命名规范

  • Given/When/Then: 经典的场景描述法。
  • Descriptive Names:
    test_calculatePrice_should_applyDiscount_when_userIsVip

5. 覆盖率目标设定

  • Line Coverage: 基础指标。但不应盲目追求 100%。
  • Branch/Path Coverage: 核心逻辑必须确保所有路径都被覆盖。
  • Mutation Testing: 通过故意破坏代码逻辑,观察测试是否失败,以此衡量测试用例的质量。

6. 测试反模式清单 (Anti-patterns)

  • Fragile Tests: 测试中包含了过多的实现细节,导致代码稍作重构(逻辑未变)测试就崩掉。
  • Slow Tests: 测试跑得太慢,导致开发者不愿频繁运行,丧失 TDD 的即时反馈优势。
  • Interdependent Tests: 一个测试的成败依赖于另一个测试的运行顺序。
  • Mocking Third-party Libraries: 不要 Mock 你不拥有的代码(Don't mock what you don't own),应该 Mock 你的适配层(Wrappers)。

7. CI 集成与自动化

  • Git Hooks: 在
    pre-commit
    pre-push
    阶段强制运行单元测试。
  • Automated Reports: 生成易读的测试覆盖率报告(如 Cobertura, LCOV)。
  • Flaky Test Management: 自动识别并隔离那些随机失败的测试用例。

常用命令/模板

Jest (JS/TS) 测试模板

import { calculateDiscount } from './pricing';

describe('Pricing Logic', () => {
  // RED Phase: Define the expectation
  it('should apply 20% discount for VIP users', () => {
    // Given
    const user = { id: 1, type: 'VIP' };
    const originalPrice = 100;

    // When
    const finalPrice = calculateDiscount(user, originalPrice);

    // Then
    expect(finalPrice).toBe(80);
  });
});

自动化运行命令示例 (Vitest)

# 启动监听模式(TDD 必备,改完代码即刻看到结果)
npx vitest watch

# 运行覆盖率分析
npx vitest run --coverage

测试代码重构 CheckList

  • 是否消除了硬编码?
  • 逻辑层和 IO 层(DB, Network)是否已解耦?
  • 类和函数的命名是否能清晰反映其单一职责(SRP)?
  • 是否存在长函数可以拆分为小的私有辅助函数?

边界与限制

  • 过度测试: 对平凡的、生成的代码(如 getter/setter)进行测试是浪费时间。
  • UI 频繁变更: 在前端 UI 极其不稳定、原型设计阶段,编写严格的 E2E 测试可能效率极低。
  • 遗留代码 (Legacy Code): 在没有测试的老代码库中引入 TDD 很难,第一步应该是先写“表征测试(Characterization Tests)”把现状固化下来。
  • 性能挑战: 某些涉及复杂算法(如加密、大规模图形渲染)的测试可能运行缓慢。
  • 文化阻力: 团队可能认为 TDD 拖慢了初期进度(实际长期来看会缩短修复 Bug 的时间)。

Generated by Skill Master - Professional Edition