testing-changes
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTesting changes
变更测试
REQUIRED BACKGROUND: the skill. The craft of the tests themselves lives in ; this skill governs which tests a change owes.
principal-engineeringwriting-unit-tests必备背景知识: 技能。测试本身的编写技巧属于 技能范畴;本技能规定了某项变更需要配套哪些测试。
principal-engineeringwriting-unit-testsOverview
概述
A test is the executable form of a claim about behavior. A change that alters behavior without touching tests is a claim nobody wrote down: the two named incident classes this skill exists to prevent are the green suite over code that could not work, and the test or gate that turned out never to run.
测试是关于行为声明的可执行形式。若变更修改了行为却未改动测试,就相当于留下了一份未被记录的声明:本技能旨在预防两类典型问题——代码无法正常运行但测试套件却显示通过,以及测试或检查环节实际上从未执行。
What a change owes
变更需配套的测试要求
- Tests change with behavior, in the same change. An empty test diff on a behavior change is a review finding, not a style preference. A pure refactor owes the opposite proof: the existing tests still pass unmodified, which is what makes it a refactor.
- A bug fix ships its regression test. Named after the failure mode (not the ticket), demonstrated red against the unfixed code and green against the fix; both halves shown, because a regression test that never went red proves only that it compiles. This is what makes the same bug impossible to reintroduce silently.
- Scenarios are concrete and include the surfaced edges. The edge cases that grounding and review turned up go into tests by name; the happy path alone tests the demo, not the change. When the change's risk is in the failure path, the failure path gets the tests (see : the typed failure surfacing IS behavior).
handling-failures - Every task carries its targeted verify command. The specific test invocation that proves this change, runnable alone, stated where the reviewer can run it. "The suite passed" vouches for nothing the suite never covered.
- Assertions must discriminate. A test that passes regardless of the change proves nothing: break the code once, watch red, unbreak. Non-discriminating assertions are how suites stay green over broken behavior.
- Aggregates that must reconcile get invariant tests. Anything on the project's declared critical paths (see the risk tiers in ) that sums, derives, or mirrors other data gets a test asserting the reconciliation itself (the conservation pattern: the aggregate equals what the raw records imply), not just point examples.
principal-engineering
- 测试随行为同步变更,且需包含在同一变更中。若行为发生变更但测试差异为空,这属于评审问题,而非风格偏好。纯重构则需要相反的证明:现有测试无需修改即可全部通过,这才是重构的核心特征。
- Bug修复需附带回归测试。回归测试需以失效模式(而非工单名称)命名,需展示在未修复代码下测试失败(红)、修复后测试通过(绿)的完整过程;这两个环节缺一不可,因为从未失败过的回归测试只能证明其能编译,无法证明其能检测Bug。只有这样,才能避免同一Bug被悄无声息地重新引入。
- 测试场景需具体且涵盖已发现的边缘情况。在问题梳理和评审过程中发现的边缘案例,需在测试中明确覆盖;仅测试正常路径只能验证演示效果,无法验证变更的完整性。若变更的风险集中在异常路径,则需针对异常路径编写测试(参考 :类型化异常暴露本身就是一种行为)。
handling-failures - 每个任务需明确对应的验证命令。需提供能单独运行、可证明变更有效性的具体测试调用命令,并告知评审者执行方式。仅说“测试套件已通过”无法证明套件未覆盖的部分无问题。
- 断言需具备区分度。无论变更与否都能通过的测试毫无意义:可先故意破坏代码,观察测试失败,再修复代码确认测试通过。缺乏区分度的断言会导致测试套件在代码已损坏的情况下仍显示通过。
- 需对账的聚合数据需编写不变性测试。项目关键路径上(参考 中的风险层级)所有涉及求和、推导或镜像其他数据的内容,都需编写测试来验证对账逻辑(守恒模式:聚合结果需与原始记录推导的结果一致),而非仅测试点示例。
principal-engineering
The red-test rule
红测规则
A red test in a gate you own gets fixed, never silenced: weakening the assertion, deleting the test, or marking it skipped to ship is converting a detected defect into an undetected one. Changing the test is legitimate exactly when the test asserted the old, wrong behavior, and the change says so explicitly. Origin is attributed first, then fixed regardless of whose it is; "pre-existing" is a footnote, never an excuse (see ).
verifying-before-done若你负责的检查环节出现测试失败(红测),需修复测试而非将其屏蔽:弱化断言、删除测试或标记为跳过以完成交付,本质是将已发现的缺陷转化为未被发现的缺陷。只有当测试断言的是旧的错误行为时,修改测试才是合理的,且需在变更中明确说明这一点。无论测试是谁编写的,都需先确认问题根源再进行修复;“预先存在的问题”只能作为备注,绝不能成为借口(参考 )。
verifying-before-doneWhat a change does not owe
变更无需配套的测试
- Tests for unreachable edges (see : fencing what cannot happen is dead code with good intentions).
scoping-changes - Tests of framework internals or generated code; test your use of them at the boundary you own.
- A test-first process: whether tests come first is workflow (the TDD skill where installed governs that); this skill governs what must exist when the change ships, whichever order produced it.
- 不可达边缘情况的测试(参考 :防护不可能发生的情况属于带有良好意图的死代码)。
scoping-changes - 框架内部或生成代码的测试;只需在你负责的边界处测试对它们的使用情况即可。
- 测试优先的流程:测试是否优先编写属于工作流范畴(由已安装的TDD技能管控);本技能管控的是变更交付时必须存在的测试,无论测试是先写还是后写。
Common mistakes
常见误区
- "Too small to test." Small changes break behavior at the same rate per line; the test takes minutes, the silent regression takes an audit.
- Testing the fix without reproducing the bug. Red-before-green is the half that proves the test sees the defect.
- Counting coverage by feel. Count the changed behaviors against the tests naming them (see the counted-coverage rule in the technical-writer plugin's truth doctrine, same principle).
- Adding the test that discriminates against nothing, ever: an assertion no plausible defect could fail. Distinct from the legitimate pinning test that deliberately passes against both old and new code to guard unchanged adjacent behavior from overcorrection; a pinning test says that is what it is for.
- “小到无需测试”。小变更每一行代码出现行为异常的概率与大变更相同;编写测试只需几分钟,而未被发现的回归问题可能需要花费大量时间排查。
- 仅测试修复后的情况,未复现Bug。先红后绿的过程才能证明测试能检测到缺陷。
- 凭感觉判断覆盖率。需将变更的行为与对应的测试逐一核对(参考技术 writer 插件真实性原则中的计数覆盖率规则,原理相同)。
- 添加永远无法区分任何情况的测试:即没有任何合理缺陷能导致其失败的断言。这与合理的固定测试不同——固定测试会故意在新旧代码下都通过,目的是防止对未变更的相邻行为过度修正;固定测试需明确说明其用途。