验收不是给自己打分,是把「感觉还行」换成一句能被证据反驳的话。
一、季度最后一天的桌面
十二月三十一日下午,罗清和把一年的两摞东西摊在桌上:左边是 47 个线上缺陷的记录,右边是 12 次发布的回归清单。他原本只想确认一下「今年质量还行」,翻到第三页就停住了——缺陷按周分布的那张图里,前六个月每月 3 到 4 个,后六个月每月 4 到 5 个,形状几乎没变。
以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。
形状没变意味着这一年他没有改变任何东西。修了 86.5 小时的缺陷,写了 214 个单元测试,加了六项发布门禁,这些都真实发生过,但它们的合力只够把缺陷数按住在原地。他一直在救火,没有一次坐下来问「火烧得比去年少了吗」。
更刺眼的是另一件事:桌上没有第四摞纸。47 个缺陷有分级、有时限、有达标记录;12 次发布有回归清单、有门禁日志;但没有一页写「这个季度质量变好了还是变差了」。判断全靠记忆,而记忆只记得最近两次事故。
验收要解决的是可比较性,不是自我评价。 一个季度结束时能拿出同一套指标,和下个季度放在一起看,才知道某个改动到底有没有用;拿不出来,所有改进都只能靠感觉确认,而感觉总是偏向「最近比较顺」。
他试着回忆这一年做过哪些改进:三月份加了六项门禁、五月份把单元测试从 0 写到 214 个、九月份补了回归清单。三件事都在记忆里,但没有任何一个数字能说明它们各自的贡献;更麻烦的是,如果明年再问一次,他还会给出同样的三件事,因为记不住的部分不会被提起。
所以这一节要做的,是把散落的记录压成两样东西:一张十项检查表,回答「该做的做了没有」;一个四维加权分,回答「做到什么程度」。前者是二元的,后者是可比的。
二、十项检查:每一项都要有证据
检查项必须配证据,否则会退化成勾选。下面十项里,每一行的「现状」都能在仓库或记录里指到具体文件,指不到的一律算未达标。
| 检查项 | 证据 | 达标线 | 现状 |
|---|---|---|---|
| 关键路径回归 | 12 次发布的回归记录 | 每次发布跑必跑 12 条 | 12/12 |
| 三层测试全量 | CI 运行日志 | 6 分钟内全绿 | 5 分 33 秒 |
| 受影响集 | 单次提交的测试耗时 | 2 分钟内 | 107.5 秒 |
| 发布门禁 | 6 项检查的执行记录 | 每次发布 6 项全绿 | 全绿 12/12,拦截 7 次 |
| 缺陷时限达标 | 47 个缺陷的处理时间 | 达标率 ≥85% | 80.9% |
| 不可逆保护 | 预演与快照记录 | 5 条路径全覆盖 | 5/5 |
| 测试数据 | 种子文件与重置脚本 | 一键重置 ≤3 秒 | 2.4 秒 |
| 外部依赖分类 | 依赖清单 | 6 个依赖全部有替身或标注只读 | 6/6 |
| 测试数据脱敏 | 测试库字段扫描 | 真实个人数据 0 条 | 0 条 |
| 季度复盘 | 复盘记录 | 4 次/年 | 0 次 |
十项里有八项达标,两项不达标:缺陷时限 80.9% 差 4.1 个百分点,季度复盘 0 次。这两项的性质完全不同——前者是执行得不够快,后者是根本没做。
八项达标里也有强弱之分。「5 分 33 秒」「107.5 秒」「2.4 秒」这类数字是自动产生的,不需要额外维护;「5/5」「6/6」「0 条」这类要靠一次人工核对,核对本身没有留痕,下个季度再查一遍才知道有没有退化。检查表最好标出哪几项是自动证据,哪几项是人工证据,后者的可信度天然低一档。
缺陷时限那一项要看分布,不能只看总数。38/47 的达标率里,P0 是 3/3、P1 是 7/9、P2 是 17/21、P3 是 11/14;拖过时限的两条 P1 都发生在同一个月,那一个月他在赶一个客户的上线,所有 P1 都被推到了周末。
季度复盘那一项没有借口。它不是被别的事挤掉的,而是从来没进过日历;没有固定时间的事,在单人产品里等于不会发生。
检查表要能区分「差一点」和「没开始」。前者给出差值就能排期,后者需要先决定要不要做;混在一张表里用同一个红叉表示,会让两类问题都被拖到明年。
十项检查还有一个隐含用途:它们是可以被别人问的。客户做供应商评估时问「你们怎么保证数据不串」,能指着「外部依赖分类 6/6」和「脱敏 0 条」回答,比说「我们很注意安全」有用得多。这也是为什么证据必须落在文件上——说得出口的前提是查得到。
三、四维加权:3.13 与 4.11 之间差了什么
十项检查是二元的,只能回答有没有;要比较季度之间的程度,需要一个带权重的分数。四个维度按对「一次事故的贡献」分配权重:覆盖 0.35、速度 0.25、可逆 0.20、记录 0.20。
| 维度 | 权重 | 现状 | 修后 | 依据 |
|---|---|---|---|---|
| 覆盖 | 0.35 | 3.0 | 4.0 | 回归 38 条已分三档;但租户隔离只有 3 个用例,12 条关键路径里 2 条仍靠手动 |
| 速度 | 0.25 | 3.5 | 4.25 | 全量 332.8 秒、受影响集 107.5 秒;扣分在 6 条 E2E 串行占 252 秒 |
| 可逆 | 0.20 | 3.0 | 4.0 | 5 条不可逆路径有预演与快照(4.7 分钟/次);删除账号没有统一冷却 |
| 记录 | 0.20 | 3.0 | 4.25 | 缺陷分级与时限在跑,38/47;一年 0 次复盘,债账本未结算 |
权重的理由是「一次事故由什么决定」。覆盖决定事故会不会发生,权重最高;速度决定发现得多早,早一小时发现,修复成本差一个量级;可逆决定发现之后能不能退回去;记录决定同类事故会不会再来一次。后两者各占两成,因为它们不阻止第一次,只缩小第二次。
评分的口径要写死,否则每个季度都会往上漂。这一版的口径是:5 分表示该项有自动化证据且覆盖全部路径,4 分表示覆盖全部路径但有一步靠人,3 分表示覆盖主路径,2 分表示只覆盖一半,1 分表示靠记忆。
按这个口径,覆盖给 3.0 是因为主路径都在,但租户隔离这类「错了不会红」的地方缺一个用例;可逆给 3.0 是因为五条路径都有预演与快照,但删除账号这类操作没有冷却期,退不回来;记录给 3.0 是因为缺陷侧齐全,复盘侧空白,两边平均。
覆盖的 0.35 权重值得单说。它高,不是因为覆盖最重要,而是因为它最贵:补一个用例要 20 到 40 分钟,改一次流水线要半天,而记录维度的改进只要把复盘放进日历。权重的作用是抵消这种成本差异,否则每个人都只会做便宜的那一项。
速度给 3.5,是四项里唯一高于 3 的。全量 5 分 33 秒、受影响集 107.5 秒,对一个人维护的项目已经够快;但 6 条 E2E 串行占了 252 秒,等于全量的四分之三,这一段的改进空间是确定的。
两列数值都要给依据,并且依据要指向同一批证据。修后那一栏尤其要克制:把每一项都写成 5.0 会让分数变成愿望清单,而下个季度真正做到的通常只有两三项;这一版只写「补上缺的那一块」能到几分,不写「全部做完」能到几分。
复算放在下一节,因为加权值的算法必须逐项摊开,否则 3.13 与 4.11 只是两个没有来源的数字。
四、复算与下季度的三个动作
加权分不是平均数,任何一个维度的变化都会被权重放大或缩小。下面把两次计算逐项摊开,同时给出季度复盘的时间账。
复算:
现状 = 0.35×3.0 + 0.25×3.5 + 0.20×3.0 + 0.20×3.0
= 1.05 + 0.875 + 0.60 + 0.60
= 3.125 → 3.13
修后 = 0.35×4.0 + 0.25×4.25 + 0.20×4.0 + 0.20×4.25
= 1.40 + 1.0625 + 0.80 + 0.85
= 4.1125 → 4.11
权重合计 0.35 + 0.25 + 0.20 + 0.20 = 1.00
差值 4.1125 − 3.125 = 0.9875 ≈ 0.99
季度复盘 4 次 × 6 h = 24 h/年,占 1,920 h 的 1.25%
从 3.125 到 4.1125,涨的 0.9875 里权重最大的覆盖贡献 0.35,记录贡献 0.25,可逆贡献 0.20,速度贡献 0.1875。这个分布说明一件事:先把覆盖补上,比先优化速度划算接近两倍。
修后分数不是许愿,每一项都对应一个能在下季度验收的动作。三个动作按投入产出排序,第一个动作同时改善两个维度,所以排在前面。
动作一:测试流水线一次改完。 补租户隔离的 3 个用例、把 2 条手动关键路径写进回归清单、把 6 条 E2E 改成两条流水并行。预计 9 小时,覆盖升到 4.0、速度升到 4.25;E2E 并行后全量从 332.8 秒降到约 210 秒。
动作二:5 条不可逆路径统一 24 小时软删除冷却。 结账、订阅变更、导出、删除账号、权限变更,五条路径共用同一套冷却与撤回入口。预计 6 小时,可逆升到 4.0。
动作三:季度复盘固定进日历。 每季最后一周的周三,2 小时准备加 4 小时会议,一年 24 小时。它不直接提升任何一项检查,但它是唯一能让下一年不再重复这一年的动作。
三个动作合计 39 小时,占验证预算 192 小时的 20.3%,剩下的 153 小时留给日常的写测试、跑回归与处理缺陷。这个比例是有意的:改进动作不能吃掉维持现状的时间,否则第一个季度就会因为「没空跑回归」而出现新的缺陷高峰。
复盘当天的议程只有三行:把十项检查逐条对证据、把四维分数和上季度比、把差值归因到具体动作。不讨论「明年要更重视质量」这类结论,因为它无法验收,也无法进入下一张表。
五、行动清单与复算验收
把十项检查、四维评分与三个动作收进一页纸,再用八条检查确认这页纸明年还能用。
- 十项检查各自写下证据位置,指不到具体文件的按未达标处理
- 检查表区分「差一点」与「没开始」,前者给差值,后者给决定
- 四维权重固定为 0.35、0.25、0.20、0.20,改动需写明理由
- 评分口径写死 1 到 5 分的判定,每季度用同一套口径
- 每次评分同时记录现状与修后两栏,差值才是可比较的部分
- 修后分数必须拆成不超过三个动作,每个动作给工时与验收点
- 季度复盘固定 4 次 × 6 h 进日历,不与发布窗口重叠
- 复盘只回答两个问题:哪项变差、下季度砍掉什么
验收标准:同一套十项检查与四维口径连做两个季度,两次的差值能归因到具体动作,而不是归因到「这个季度比较忙」。
使用边界与实操验收
边界一:加权分不是行业基准。 权重按「一次事故的贡献」定,换一个产品、换一个阶段就该重算;把 3.13 拿去和别人的分数比较没有意义,只有自己连续四个季度的曲线有意义。
边界二:十项检查不覆盖全部质量。 它衡量的是可验证的部分,不含架构合理性、代码可读性与用户实际感受;这三样要靠架构评审与用户访谈,本篇不论。
边界三:评分依赖证据的诚实度。 把「大概跑过」记成达标,整张表就失去意义;证据要能指到文件、日志或提交,指不到就写未达标,这一条比评分口径更重要。
边界四:本文只讨论单人产品的季度验收。 团队的质量门禁、评审流程与合规审计不在范围内;本文不构成对任何具体项目质量水平或交付能力的承诺。
关键参考与核验范围
- OWASP ASVS :用于核对「检查项必须配可验证证据」的组织方式,以及分级要求的写法。
- The Practical Test Pyramid :用于核对覆盖维度里分层测试的判定依据。
- GitHub Actions 文档 :用于核对 CI 运行时长与门禁执行记录能否作为证据留存。
- Semantic Versioning :用于核对不可逆变更与版本号之间的关系,辅助可逆维度的评分。
以上链接于 2026-10-26 实测可公开访问;未核验版本、价格与配额。核验日期:2026-10-26。
范围声明:本文的缺陷数、工时、权重与评分均为教学假设,落地时以实际记录与产品阶段为准;只讨论季度验收的度量方式,不讨论具体测试框架、发布流程或团队协作制度。
系列导航
- 回到本组目录:一个人的质量守门:验证预算、回归清单与发布门禁
- 上一篇:验证的边际收益:什么时候可以不写测试
- 下一篇:无(本组共 10 篇,本篇为最后一篇)
- 相关:一个人的运维:可用性、告警、事故与值班
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。