keep-it-working

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Keep it working

保持功能正常运行

The goal is not tests. The goal is that the thing they got working today still works on demo day, after forty more changes and an agent that doesn't know what it isn't supposed to touch.
So the question after every feature is never "should I write tests." It's would we notice if this broke, and how bad is it if we don't. Answer those two and the level picks itself.
目标不是写测试。目标是他们今天调通的功能,在经过四十次变更、还有一个分不清哪些不该碰的Agent之后,到演示日依然能正常运行。
所以每个功能完成后,问题从来不是「我该不该写测试」,而是**「如果这个功能坏了我们能发现吗?如果没发现后果有多严重?」** 回答了这两个问题,该用什么级别的验证就一目了然了。

The ladder

验证阶梯

Pick the cheapest rung that actually catches the failure. Climbing higher than the risk deserves is how a two-week sprint turns into a testing project.
RungUse whenWhat you do
1. Look at itThe failure would be obvious on sight — layout, copy, colour, spacingOpen the page. Look. Done. No test earns its keep here
2. Walk the pathMulti-step flow you can still click through — sign up → create → see it listedDrive the running app once, end to end, and report what you saw. No setup, no files. See
playwright
3. Write one testBreaking it would be silent, or checking by hand takes more than a minute — background jobs, webhooks, anything with a database round tripOne test for the happy path. Not a suite. For whole flows,
playwright
4. Test firstYou can state the rule before the code exists, or you're fixing a bug you can reproduceWrite the failing test, watch it fail, then make it pass
选择能真正发现故障的最低成本层级。如果做的验证远超风险所需,两周的Sprint就会变成一个纯测试项目。
层级适用场景操作方式
1. 肉眼检查故障一眼就能看出来——布局、文案、颜色、间距打开页面,看一眼就完事。这里写测试完全没必要
2. 走查流程可以点击走完的多步骤流程——注册 → 创建 → 查看列表从头到尾操作一遍运行中的应用,记录你看到的结果。不需要配置,不需要写文件。可使用
playwright
3. 编写单个测试故障不会直观显现,或者手动检查要花一分钟以上——后台任务、webhook、任何涉及数据库交互的内容为正常路径写一个测试即可,不用搭建测试套件。如果是完整流程,使用
playwright
4. 测试先行你能在写代码之前就明确规则,或者你在修复一个可复现的bug先编写会失败的测试,确认它确实失败,再让测试通过

When test-first actually pays

测试先行真正划算的场景

Not a principle, a calculation. Write the test first when:
  • You can say the rule as a sentence with inputs and outputs. "Orders over ₹2000 ship free, except international." Pricing, scoring, quotas, limits, permissions, date maths. The sentence is the test, so writing it first costs almost nothing and pins the rule down before the code wanders off.
  • The bug is reproducible. Always. A bug you can trigger is a test you can write in a minute, and it's the only way to know the fix worked and stays working. This is the single highest-value test in any sprint project.
  • Many branches. Empty, one, many, too many, wrong type, expired, already used. If you'd otherwise check five cases by clicking, checking them in code is faster on the second run.
  • You'll change it repeatedly. Anything you already rewrote once will be rewritten again.
Don't write the test first when:
  • It's how something looks. Tests can't see. Use rung 1 or 2.
  • You don't know what correct is yet. Explore, get it working, then pin it down with a test if it earned one. Exploration first is fine — just don't keep the exploration and call it done.
  • It's a one-off — a migration you'll run once, a script that seeds fake data, a prototype you've already agreed to throw away.
这不是原则,而是成本计算。满足以下情况时可以先写测试:
  • 你能用一句话把规则描述清楚,包含输入和输出。 「订单满₹2000免运费,国际订单除外」。定价、评分、配额、限制、权限、日期计算。这句话本身就是测试,所以先写测试几乎没什么额外成本,还能在代码写偏之前把规则定死。
  • bug是可复现的。 永远都是。能触发的bug花一分钟就能写成测试,这也是唯一能确认修复有效且不会再出问题的方法。这是所有Sprint项目中价值最高的测试。
  • 分支情况多。 空值、单个、多个、过多、类型错误、已过期、已使用。如果你本来就要点来点去检查五种情况,那用代码检查在第二次运行时就会更快。
  • 你会反复修改它。 任何你已经重写过一次的东西,肯定还会再改。
以下情况不要测试先行:
  • 是视觉相关的内容。 测试看不见。用第1或第2层级。
  • 你还不知道什么是正确结果。 先探索,把功能跑通,如果有必要的话再用测试固定下来。先探索完全没问题——只是别把探索阶段的代码当成最终成品。
  • 是一次性的东西——只会运行一次的迁移脚本、生成假数据的脚本、已经说好要扔掉的原型。

The rule that isn't negotiable

不可妥协的规则

Anything that broke once gets a test. No judgment call, no ladder. It broke, so it can break again, and now you know exactly how to trigger it.
This is what stops the sprint's worst pattern: fix something on Tuesday, agent quietly re-breaks it on Thursday, nobody notices until the demo.
任何出过一次问题的东西都必须加测试。 不用判断,也不用走阶梯。它既然坏过,就可能再坏,而且现在你已经明确知道怎么触发它了。
这能避免Sprint中最糟糕的模式:周二修了个问题,周四Agent悄悄把它又搞坏了,直到演示才有人发现。

Don't build a test setup before it's earned

不要提前搭建测试环境

The sprint stack ships without a test runner, and that's correct — most work lands on rungs 1 and 2.
The first time a change genuinely lands on rung 3 or 4, install the smallest possible runner and write that one test. Not a config, not a suite, not coverage. If setting it up is going to take more than a few minutes of their sprint, say so and offer rung 2 instead — then let them choose.
Sprint项目的初始技术栈不带测试运行器,这是合理的——大部分工作都只需要第1、2层级的验证。
第一次真的需要用到第3或第4层级的验证时,再安装最小巧的测试运行器,写那一个测试就行。不用搞配置,不用写测试套件,不用管覆盖率。如果搭建环境要花掉他们Sprint中好几分钟的时间,就直说,然后提议用第2层级代替——让他们自己选。

Once tests exist

有了测试之后

  • Run them after every change, not just the change that touched them.
  • Red suite? Stop. Fix it before adding anything new. Building on a red suite is how an afternoon disappears.
  • Report every failure by name, including ones you didn't cause. A red test that scrolled past unmentioned is a lie by omission.
  • Keep them honest: the name says the behaviour, the assertion is on real behaviour and not on a mock, one behaviour per test. A test that can't fail is worse than no test, because it buys false confidence.
  • 每次变更后都要运行测试,不只是改了相关代码才跑。
  • 测试套件变红(失败)?立刻停手。先修好再加新东西。在失败的测试套件上堆代码,一下午的时间就这么没了。
  • 每个失败的测试都要明确说出来,哪怕不是你搞坏的。没提的失败测试就是隐瞒的谎言。
  • 保持测试的真实性:测试名称要说明对应的行为,断言要针对真实行为而不是mock,每个测试只测一个行为。一个永远不会失败的测试比没有测试还糟,因为它会带来虚假的信心。

How to talk about this

如何沟通这件事

Never "you should have written tests." They're learning to ship, and the ladder exists so they don't have to carry that guilt.
Say what's worth protecting and what it costs: "the pricing rule is the kind of thing that breaks quietly — two minutes to lock it down, want me to?" Then respect the answer. If they say no, note it and move on;
checkpoint
is still underneath them either way.
When a test catches a regression, say so out loud. That's the moment the idea sells itself.

Ours. The red-green discipline and the test-honesty rules are adapted from obra/superpowers, MIT License — the ladder and the "when does this pay" triage are ours, because sprint builders need to ship first and prove second.
永远别说「你本来该写测试的」。他们在学习如何交付产品,而验证阶梯的存在就是为了不让他们有这种负罪感。
要说清楚什么值得保护、成本是多少:「定价规则这种东西坏了很难发现——花两分钟就能加个测试锁定,要我弄吗?」 然后尊重对方的答案。如果他们说不用,记下来继续就行;反正底下还有
checkpoint
兜着。
当测试抓到了回归问题,要大声说出来。这时候这个理念的价值不言自明。

注:红-绿纪律和测试真实性规则改编自 obra/superpowers,MIT 许可证——验证阶梯和「什么时候划算」的分类是我们原创的,因为Sprint开发者需要先交付,再验证。