# Tdd

> 测试驱动开发。当用户想以测试先行的方式构建功能或修 bug、提到 "red-green-refactor"，或要加集成测试时使用。

- Skill: `cislunarspace/tdd` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add cislunarspace/tdd`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cislunarspace/tdd/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cislunarspace (https://skillmd.com/u/cislunarspace)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cislunarspace/tdd

---


# 测试驱动开发

TDD 就是红 → 绿循环。这个 skill 是让那个循环产出值得保留的测试的参照：什么是好测试、测试该落在哪、反模式、循环的规矩。每节在每个循环都适用——循环之前和之中查阅，不是之后。

探索代码库时，读 `CONTEXT.md`（如果存在），让测试名和接口术语匹配项目的领域语言；尊重你要触碰区域的 ADR。

## 什么是好测试

测试通过公开接口验证行为，不验证实现细节。代码可以彻底重写；测试不应该变。好测试读起来像规约——"user can checkout with valid cart"准确告诉你存在什么能力——并在重构后存活，因为它不关心内部结构。

示例见 [tests.md](tests.md)，mock 指引见 [mocking.md](mocking.md)。

## 接口——测试落在哪

**接口**（seam）是你测试的公开边界：你能观察行为、又不把手伸进内部的那一面。测试落在接口上，永远不直接对内部下手。

**只在预先商定的接口上测试。** 写任何测试之前，把要测的接口列出来、跟用户确认。没确认过的接口不写测试。你没法什么都测——预先约定接口，才能让测试精力落在关键路径和复杂逻辑上，而不是散到每个边界情况。

问："公开接口是什么？该测哪些接口？"

当那个接口的形状本身存疑时——模块有多深、接口放在哪、接口该暴露什么——用 `/codebase-design` skill 获取术语。它是 模块、接口、深度、适配器、杠杆、局部性 这些术语的共享来源，是一份供查阅的参照，不是一次要跑的会话。

## 反模式

- **耦合实现** ——mock 内部协作者、测私有方法，或通过旁路验证（查数据库而不是走接口）。特征：行为没变，一重构测试就挂。
- **同义反复** ——断言的期望值用代码自身的方式重新算了一遍（`expect(add(a, b)).toBe(a + b)`、用同样方式手工算出再贴上的快照、常量跟自己相等），所以它构造上就过，永远没法跟代码不一致。期望值必须来自独立的真值源——已知正确的字面量、手算的例子、规约。
- **水平切片** ——先把所有测试写完，再写全部实现。批量测试验证的是_想象出来的_行为：你测的是东西的_形状_，而不是用户面对的行为；测试对真实改动变得不敏感；你在还没理解实现之前就先把测试结构定死了。改成**垂直切片** ——一个测试 → 一段实现 → 重复，每个测试是一条 tracer bullet，回应上一个循环教给你的东西。

## 循环的规矩

- **先红再绿。** 先写挂掉的测试，再写刚好够它过的代码。不要预判未来的测试，不要加投机性的功能。
- **一次一片。** 每个循环一个接口、一个测试、一段最小实现。
- **重构不在循环内。** 它属于 review 阶段（见 `code-review` skill），不属于红 → 绿的实现循环。

