test-first-by-evidence
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTest First by Evidence
循证测试先行
Core principle. A test you did not watch fail proves nothing. It might test the wrong thing, and you would never know.
- This is pointed forward. One says no hypothesis before a command that reproduces. This one says no implementation before a test that failed.
debugging-by-evidence - The weight sits in Watch it fail. Everything else is what to do once the red is real.
- You opened this in the middle of something. This is how to do that work, not a replacement for it. Name what you were doing before you start, and return to it when this is done.
核心原则:未亲眼见证失败的测试毫无意义。它可能测试了错误的内容,而你永远不会察觉。
- 这是前瞻性的(循证调试)。前者要求在复现问题的指令出现前不做假设,后者要求在测试失败前不进行实现。
debugging-by-evidence - 关键在于“观察其失败”。其他步骤都是在测试确实失败(红态)后的操作。
- 你是在中途打开这份文档。这是完成当前工作的方法,而非替代原有工作。开始前明确你正在做的事情,完成后回到原工作。
The law
法则
NO PRODUCTION CODE WITHOUT A TEST YOU WATCHED FAIL- Code written before its test is unproven, and gets re-derived from a red rather than wrapped in a test that passes immediately.
- Make it recoverable before removing anything. Discarding work the human has not agreed to discard is not yours to do.
- A test that passes the first time you run it is not a test yet. It describes what the code already does.
- A test that errors is not a red. An error is a broken test; a failure is a working test with nothing to satisfy it.
NO PRODUCTION CODE WITHOUT A TEST YOU WATCHED FAIL- 先于测试编写的代码未经验证,应从测试失败状态重新推导,而非直接用立即通过的测试包裹。
- 在删除任何内容前确保可恢复。未经相关人员同意,不得丢弃已完成的工作。
- 首次运行即通过的测试尚不能称为测试。它仅描述了代码已有的行为。
- 报错的测试并非红态。报错是测试本身存在问题;失败是测试正常运行但没有内容能满足其断言。
Establish before the first test
编写首个测试前需明确的事项
- Never ask what the repository answers. Three things settle the setup, and it holds all three.
- The command this project already uses to run tests.
- Where its tests live, and what a neighbouring test looks like.
- The runner, so the failure output means something to you.
- Read one nearby test before writing yours. Style is local, and a test that fights the local style is a second convention.
- 不要询问仓库的默认设置。以下三点决定了测试环境,且项目已包含这些内容:
- 项目已在使用的测试运行命令。
- 测试文件的存放位置,以及相邻测试的样式。
- 测试运行器,这样你能理解失败输出的含义。
- 编写测试前先阅读一个相邻的测试。测试风格具有本地化特点,与本地风格相悖的测试会引入第二种规范。
Which rules to read
应阅读哪些规则
This table is a gate, not a checklist. Match the left column against what is in front of you.
- One rule per row. Enter at the matched row, then follow the cycle in order.
- A small change reads two rows. A new subsystem reads most of them. That difference is the point.
- Where two rows match, read both. Under-reading costs a wrong test. Over-reading costs one file.
| If you see... | Read |
|---|---|
| a test about to be written, or one that passed on its first run | |
| a red you trust and code to write against it | |
| no obvious place for the test, or a choice between unit, integration, and end to end | |
| mocks, fixtures, or assertions on calls rather than on results | |
| implementation that already exists with no test behind it | |
| a bug report, a stack trace, or a regression | |
| a test that is hard to write, or needs everything mocked | |
Discriminators.
- Watch it fail against code written first. The first owns the normal path. The second owns the recovery when the order was already broken.
- Where it goes against what makes it honest. Placement decides which seam. Honesty decides what it asserts once it is there.
- Bug fix against watch it fail. A bug fix starts from a red that reproduces a defect. The general case starts from a red that describes a wish.
Default stance.
- Write the test, run it, and watch it fail before writing any implementation.
- Then write the least code that passes, and run the whole suite.
- Never claim a phase you have not observed. A predicted failure is not a red.
此表格是指引而非检查清单。将左列内容与你当前的场景匹配。
- 每行对应一条规则。从匹配的行进入,然后按顺序遵循循环步骤。
- 小变更只需阅读两行。新子系统则需阅读大部分规则。这种差异正是关键所在。
- 若两行都匹配,则阅读两者。阅读不足会导致测试错误,阅读过多仅多花一点时间。
| 若你遇到... | 阅读 |
|---|---|
| 即将编写的测试,或首次运行即通过的测试 | |
| 可信的红态测试,以及需针对其编写的代码 | |
| 测试位置不明确,或需在单元测试、集成测试、端到端测试间选择 | |
| 使用Mock、测试数据或调用断言而非结果断言 | |
| 已存在的实现代码但无配套测试 | |
| Bug报告、堆栈跟踪或回归问题 | |
| 难以编写的测试,或需要大量Mock的测试 | |
区分要点
- 观察失败 vs 代码先写:前者适用于常规流程,后者适用于顺序已被打破时的补救。
- 测试位置 vs 测试真实性:位置决定测试的切入点,真实性决定测试的断言内容。
- Bug修复 vs 观察失败:Bug修复从复现缺陷的红态测试开始,常规场景从描述需求的红态测试开始。
默认准则
- 先编写测试,运行并观察其失败,再编写任何实现代码。
- 然后编写能通过测试的最少代码,并运行整个测试套件。
- 切勿声称未观察到的阶段。预测的失败并非真实的红态。
Say which phase you are in
明确当前所处阶段
Report it every time. Each phase licenses only what it names.
| Phase | Means | Licenses |
|---|---|---|
| nothing written yet | writing one test, nothing else |
| the test ran and failed for the stated reason | implementation |
| the test passes and so does everything else | refactoring |
| duplication and names cleaned, still green | the next test |
- Skipping a phase is the failure this skill exists to prevent.
- requires a run you performed. Not a prediction that it would fail.
RED - includes the rest of the suite. One new green and three new reds is not green.
GREEN
每次都要说明。每个阶段仅允许对应操作。
| 阶段 | 含义 | 允许操作 |
|---|---|---|
| 尚未编写任何内容 | 编写一个测试,无其他操作 |
| 测试已运行并因明确原因失败 | 编写实现代码 |
| 测试通过且其他所有测试也通过 | 重构代码 |
| 已清理重复代码和命名,测试仍为绿态 | 编写下一个测试 |
- 跳过阶段正是此技能要预防的错误。
- 阶段要求你亲自运行测试。而非预测它会失败。
RED - 阶段包含整个测试套件。仅新增测试通过但其他三个测试失败不属于绿态。
GREEN
Do not skip this when
以下情况请勿跳过此流程
- The change is one line. A one-line change to the wrong line is still wrong.
- The code is too simple to break. Simple code breaks. The test costs thirty seconds.
- You already tested it by hand. Manual testing leaves no record and does not re-run.
- You will add tests after. Tests written after pass immediately, which proves nothing about whether they can catch anything.
- You are only exploring. Fine. Throw the exploration away and start again with a test.
- 变更仅一行代码。一行代码改到错误位置仍然是错误的。
- 代码过于简单不会出错。简单代码也会出错,编写测试仅需30秒。
- 已手动测试过。手动测试没有记录且无法重复运行。
- 打算之后再补测试。事后编写的测试会立即通过,无法证明它们能否发现问题。
- 仅在进行探索性开发。可以,但请丢弃探索内容,重新从测试开始。
Routing
指引
- The table above selects the rule. Read a selected rule in full, and say which one you opened, in one line.
- Judging tests inside a change under review belongs to a review of the diff, not here.
- Choosing a framework is a project decision, not this skill's.
- A direct instruction from the user outranks anything here.
- 上述表格选择对应规则。完整阅读选中的规则,并用一句话说明你打开了哪条规则。
- 评审变更中的测试属于差异评审范畴,不属于此技能的内容。
- 选择测试框架是项目层面的决策,不属于此技能的范畴。
- 用户的直接指令优先级高于此处的所有内容。