Loading...
Loading...
Compare original and translation side by side
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRSTNO PRODUCTION CODE WITHOUT A FAILING TEST FIRSTdigraph tdd_cycle {
rankdir=LR;
red [label="RED\nWrite failing test", shape=box, style=filled, fillcolor="#ffcccc"];
verify_red [label="Verify fails\ncorrectly", shape=diamond];
green [label="GREEN\nMinimal code", shape=box, style=filled, fillcolor="#ccffcc"];
verify_green [label="Verify passes\nAll green", shape=diamond];
refactor [label="REFACTOR\nClean up", shape=box, style=filled, fillcolor="#ccccff"];
record [label="Record in\nPhase 3 artifact", shape=box];
red -> verify_red;
verify_red -> green [label="yes"];
verify_red -> red [label="wrong\nfailure"];
green -> verify_green;
verify_green -> refactor [label="yes"];
verify_green -> green [label="no"];
refactor -> verify_green [label="stay\ngreen"];
verify_green -> record;
}digraph tdd_cycle {
rankdir=LR;
red [label="RED\nWrite failing test", shape=box, style=filled, fillcolor="#ffcccc"];
verify_red [label="Verify fails\ncorrectly", shape=diamond];
green [label="GREEN\nMinimal code", shape=box, style=filled, fillcolor="#ccffcc"];
verify_green [label="Verify passes\nAll green", shape=diamond];
refactor [label="REFACTOR\nClean up", shape=box, style=filled, fillcolor="#ccccff"];
record [label="Record in\nPhase 3 artifact", shape=box];
red -> verify_red;
verify_red -> green [label="yes"];
verify_red -> red [label="wrong\nfailure"];
green -> verify_green;
verify_green -> refactor [label="yes"];
verify_green -> green [label="no"];
refactor -> verify_green [label="stay\ngreen"];
verify_green -> record;
}npm test path/to/test.test.tsundefinednpm test path/to/test.test.tsundefinedrejects empty email with clear error messagenpm test src/forms/email.test.tsundefinedrejects empty email with clear error messagenpm test src/forms/email.test.tsundefined**GREEN Phase:**
- Implementation: Added null check for email field
- Command: `npm test src/forms/email.test.ts`
- Result: PASS
- GREEN verified: ✅**GREEN阶段:**
- 实现内容:为邮箱字段添加空值检查
- 命令:`npm test src/forms/email.test.ts`
- 结果:通过
- GREEN阶段验证:✅**REFACTOR Phase:**
- Extracted `validateRequired(field, name)` helper
- Renamed `submitForm` to `processFormSubmission` for clarity
- All tests still passing: ✅**REFACTOR阶段:**
- 提取`validateRequired(field, name)`辅助函数
- 将`submitForm`重命名为`processFormSubmission`以提升清晰度
- 所有测试仍通过:✅| Excuse | Reality |
|---|---|
| "This is just a simple fix, no test needed" | Simple code breaks. Test takes 30 seconds. |
| "I'll test after confirming the fix works" | Tests passing immediately prove nothing. You never saw it catch the bug. |
| "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
| "I already manually tested it" | Ad-hoc ≠ systematic. No record, can't re-run, no regression protection. |
| "Deleting working code is wasteful" | Sunk cost fallacy. Keeping unverified code is technical debt. |
| "TDD is dogmatic, I'm being pragmatic" | TDD IS pragmatic. Finds bugs before commit, enables refactoring. |
| "I'll keep the code as reference" | You'll adapt it. That's testing after. Delete means delete. |
| "Test hard = design unclear" | Listen to the test. Hard to test = hard to use. Simplify design. |
| "I need to explore first" | Fine. Throw away exploration, start TDD fresh. |
| "This is different because..." | It's not. The rules don't have exceptions. |
| 借口 | 实际情况 |
|---|---|
| “这只是个简单修复,不需要测试” | 简单代码也会出错。编写测试只需30秒。 |
| “我先确认修复有效,之后再写测试” | 测试立即通过毫无意义,你永远无法确认它是否能捕获bug。 |
| “事后写测试能达到同样目的” | 事后写测试是“验证代码做了什么”,而先写测试是“定义代码应该做什么”。 |
| “我已经手动测试过了” | 临时测试≠系统化测试。没有记录,无法重复执行,也无法提供回归保护。 |
| “删除可用代码是浪费” | 沉没成本谬误。保留未验证的代码就是技术债务。 |
| “TDD太教条,我这是务实” | TDD才是务实的做法。它能在提交前发现bug,支持安全重构。 |
| “我要保留代码作为参考” | 你会修改它的,这本质还是事后测试。删除就意味着彻底删除。 |
| “测试难度大=设计不清晰” | 倾听测试的反馈。难测试的代码通常也难使用,简化设计即可。 |
| “我需要先探索一下” | 没问题。探索代码可以丢弃,之后从零开始用TDD实现。 |
| “这个情况不一样,因为……” | 没有不一样的情况。规则没有例外。 |
undefinedundefinedtest/features/x.test.tstest/features/x.test.tstest/bugs/issue-123.test.tsundefinedtest/bugs/issue-123.test.tsundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedtest/forms/validation.test.ts$ npm test test/forms/validation.test.ts
FAIL: Expected 'Email is required', got undefinedsubmitForm()validateRequired()test/forms/validation.test.ts$ npm test test/forms/validation.test.ts
失败:预期为'Email is required',实际得到undefinedsubmitForm()validateRequired()test/utils/array.test.ts$ npm test test/utils/array.test.ts
FAIL: TypeError: Cannot read property 'map' of undefinedprocessItems()test/utils/array.test.ts$ npm test test/utils/array.test.ts
失败:TypeError: Cannot read property 'map' of undefinedprocessItems()npm testundefinednpm testundefinedreferences/rationalizations.mdreferences/rationalizations.md