tdd
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesetdd
TDD
The agent codes better with a tight feedback loop than with a long
specification. A failing test is the tightest loop there is: it states the
target, and the target either goes green or it does not.
Agent 在紧密反馈循环中比面对冗长规范能编写出更好的代码。失败测试是最紧密的反馈循环:它明确目标,而目标要么变为 Green,要么没有。
The loop
循环
- Red. Write one failing test that states the next slice of behavior. Run it. Confirm it fails for the right reason - a test that passes before you write the code is testing nothing. If it errors instead of failing on the assertion, fix the test setup first.
- Green. Write the least code that makes the test pass. Not the general solution, not the abstraction - the minimal move. Run the test. Green.
- Refactor. Now clean up with the test as a net: remove duplication, name things, simplify. Re-run after every edit. Behavior is frozen; only the shape changes.
- Repeat for the next slice. Small slices. The rate of feedback is the speed limit - never take on a step too big to hold a single test.
- Red. 编写一个失败的测试,明确下一小段行为。 运行测试。确认它因正确的原因而失败——在你编写代码前就通过的测试没有验证任何东西。如果测试是报错而非断言失败,应先修复测试设置。
- Green. 编写能让测试通过的最少代码。不是通用解决方案,也不是抽象层——只做最小改动。运行测试。变为 Green。
- Refactor. 现在以测试作为安全网进行清理:消除重复、合理命名、简化实现。每次编辑后都重新运行测试。行为保持不变,改变的只有代码形态。
- 针对下一小段行为重复上述过程。小步推进。反馈速度就是速度上限——不要承接大到单个测试无法容纳的步骤。
What makes a test worth writing
什么样的测试值得编写
- Tests behavior, not implementation. Assert on the observable result, not on which private method got called. A test that breaks on every refactor is a liability.
- One reason to fail. Each test pins one behavior. When it goes red you should know what broke without reading the body.
- Real seams, minimal mocks. Mock at the system boundary (network, clock, filesystem), not internal collaborators. A test that mocks the thing under test asserts nothing.
- No tautologies. A test that restates the implementation (after setting
expect(x).toBe(x)) verifies nothing. Assert the value the behavior should produce.x
- 测试行为,而非实现。 断言可观察的结果,而不是断言调用了哪个私有方法。每次重构都会失效的测试是一种负担。
- 只有一个失败原因。 每个测试固定一种行为。当它变为 Red 时,你无需阅读测试主体就知道哪里出了问题。
- 使用真实的接缝,最少使用 mock。 在系统边界(网络、时钟、文件系统)处使用 mock,而不是针对内部协作者。mock 被测对象本身的测试没有验证任何东西。
- 不要同义反复。 重复实现逻辑的测试(设置 后使用
x)没有验证任何东西。应断言行为应产生的值。expect(x).toBe(x)
When to reach for it
何时使用
Reach for TDD when the behavior is specifiable and a test can pin it: business
logic, parsers, state machines, bug fixes (write the failing case first, then
fix). Skip it for pure exploration, throwaway spikes, and layout-only UI where
a test asserts nothing a human would not eyeball.
当行为可以被明确描述且测试能够将其固定时,使用 TDD:业务逻辑、parser、状态机、缺陷修复(先编写失败用例,再修复)。对于纯探索、一次性 spike,以及仅涉及布局且测试无法断言任何人工肉眼可判断内容的 UI,则无需使用。
Output contract
输出约定
Show each red-green transition, not just the final green. If a test is hard to
write, say what the difficulty reveals about the design - untestable code is
usually badly-seamed code, and that is a finding, not an obstacle.
展示每一次 Red-Green 转换,而不只是最终的 Green。如果某个测试难以编写,应说明这一难点揭示了哪些设计问题——不可测试的代码通常意味着接缝设计不佳,这是一项发现,而不是障碍。