“质量怎么样?”——测试团队被问得最多、答得最虚的问题。答"用例都过了"没意义(覆盖多少?什么级别的用例?),答"覆盖率 85%"更没意义(行数而已)。度量体系的终点不是仪表盘好看,是让"质量好不好"变成一个有数据支撑、可追踪、可归因的回答。这篇讲度量体系的完整设计:指标分层、防刷分机制、数据出口。
一、指标分层:不同角色看不同层
1 2 3 4 5 6 7 8 9 10 11 12
| ┌─ L0 管理层(月度,5 分钟看完)─────────────────┐ │ 质量结论:好 / 有风险 / 差(显式结论,不是数字堆)│ │ 3 个趋势线:线上缺陷率、发布成功率、MTTR │ └──────────────────────────────────────────────┘ ┌─ L1 测试 leader(周度)──────────────────────┐ │ 风险敞口:遗留缺陷×严重度、flaky 率、风险覆盖率 │ │ 机制产出:门禁拦截数、灰度拦截数、左移发现占比 │ └──────────────────────────────────────────────┘ ┌─ L2 一线测试/研发(每日)─────────────────────┐ │ 执行状态:今天跑了什么、红了什么、谁在等环境 │ │ 个案指标:用例 flaky 分、模块缺陷密度、我的缺陷 │ └──────────────────────────────────────────────┘
|
分层的原则:每层只放"该层要做的决策"对应的指标。管理层看到"用例执行次数"是噪音,一线看到"季度质量指数"是玄学——指标放错层 = 两层都没用。
二、核心指标定义(每个都有公式和陷阱)
1. 线上缺陷率(L0 核心)
1 2 3 4 5 6
| 定义:每万用户·天的线上缺陷数(P0+P1) 公式:线上 P0/P1 缺陷数 / (活跃用户数 × 天数) / 10000 陷阱: ❌ 用"缺陷数/版本"——版本大小不一,没法比 ❌ 不区分严重度——10 个 P3 比 1 个 P0 严重? ✅ 归一化(用户·天)+ 只算 P0/P1 + 分业务线看
|
2. 发布成功率(L0)
1 2 3 4 5
| 定义:无需回滚/热修的发布占比 公式:(发布总数 - 回滚发布 - 热修发布) / 发布总数 陷阱: ❌ 只算"回滚"——"灰度中发现、未全量就停"的发布不算失败?要算(部分失败) ✅ 三态:成功 / 灰度中止 / 全量后回滚,分开统计
|
3. MTTR(L0,缺陷从发现到关闭)
1 2 3 4 5 6 7 8
| 定义:缺陷生命周期时长(按严重度分桶) P0: 中位数目标 < 4h,P1 < 24h,P2 < 7d 陷阱: ❌ 平均数(一个挂 30 天的 P2 把均值拉爆,掩盖 P0 的恶化) ✅ 中位数 + 分位数(P90)+ 分严重度 ❌ 只看"关闭时长"——把"挂着不处理"当快 ✅ 拆开看:响应时长(发现→认领)+ 修复时长(认领→待验证)+ 验证时长 三段各自有 owner(响应=值班机制,修复=研发,验证=测试排期)
|
4. flaky 率(L1,测试系统健康度)
1 2 3 4
| 定义:近 7 天被判定 flaky 的用例 / 总用例 健康线 < 2%(详见 flaky 治理篇) 价值:它是"测试结果可信度"的代理指标—— flaky 率高时,L0 的所有"通过率"指标都要打折扣
|
5. 风险覆盖率(L1,测得值不值)
1 2 3 4
| 定义:被用例覆盖的风险项 / 风险清单 风险项来源:历史缺陷归因 + 架构依赖 + 本次改动 blast radius 价值:回答"这次发版的风险面测全了吗"(发版决策依据, 详见覆盖率篇/灰度篇)
|
6. 缺陷发现阶段分布(L1,左移成效)
1 2 3
| 定义:缺陷按发现阶段(评审/PR/测试/线上)的占比 价值:左移的唯一诚实成绩单(详见测试左移篇) ——"左移了多少"不靠口号靠这个分布
|
7. 门禁拦截率(L1,机制产出)
1 2 3
| 定义:被 CI 门禁拦下的问题 / 全部问题(含测试阶段发现的) 价值:证明"机器在干活"——拦截率为 0 的门禁 = 摆设 分机制看:PR 门禁 / 契约 / 灰度判据各自的拦截数
|
三、防刷分:度量会塑造行为(古德哈特定律)
"当一个指标变成目标,它就不再是好指标"——度量体系最大风险是被刷分。四个防刷分设计:
1. 指标成对出现(矛和盾同时看)
1 2 3 4 5 6 7 8 9 10 11
| 单看"用例数" → 刷用例 配对:用例数 + 单条用例平均执行时长(刷的水用例跑得飞快)
单看"通过率" → 放松断言 / 隔离真失败 配对:通过率 + 断言密度(每用例断言数)+ flaky 率
单看"缺陷数下降" → 少报缺陷 配对:缺陷数 + 线上缺陷率(内部报少了,线上会补回来)
单看"覆盖率" → 写无断言用例 配对:覆盖率 + 伪断言率(is not None 类断言占比)
|
原则:每个"可被刷"的指标必须配一个"刷了会受伤"的指标,两个同时看,刷分无利可图。
2. 指标只考核趋势不考核绝对值
1 2 3 4 5
| ❌ "覆盖率必须 85%"(达标后没人再管,跌破时找借口) ✅ "覆盖率环比不下降 + 增量 ≥ 80%"(关注变化,不给刷分终点)
❌ "缺陷数 ≤ 5"(压到 5 以下开始藏缺陷) ✅ "线上缺陷率趋势 + 内部缺陷/线上缺陷比"(内外对照)
|
3. 数据可下钻(防"汇报数字"和"真实数字"两张皮)
1 2 3 4 5 6
| L0 的每个数字必须能下钻到 L2 个案: 管理层看到"线上缺陷率上升" → 下钻:哪条业务线? → 下钻:哪个版本引入? → 下钻:具体哪几个缺陷?当时的发布单/门禁记录? 任何一层下钻不通 = 上层数字是"汇报出来的"不是"跑出来的"
|
4. 度量数据自动采集,禁止手填
1 2 3 4 5 6 7
| 所有指标从系统直接取数: 缺陷数据 ← 缺陷平台 API 发布数据 ← 发布平台状态机 执行数据 ← CI 结果库 门禁拦截 ← CI 拦截日志 手填指标 = 可美化指标 = 三个月后失去信用 唯一例外:定性判断("带病发布决策是否合理")需要人填,但必须附数据引用
|
四、数据出口:度量不只是看板
1 2 3 4 5 6 7 8 9 10 11 12
| 1. 月度质量报告(L0 层,自动生成 + 测试 leader 批注) → 给管理层:3 个趋势 + 1 个显式结论 + 下季度风险预告 2. 周度风险清单(L1 层,自动) → 遗留缺陷×严重度排序、flaky 隔离区、风险覆盖缺口 → 每项带 owner(无 owner 的风险项 = 没管理的风险) 3. 每日执行状态(L2 层,自动推送) → 今日常规:跑了 X,红 Y(其中 flaky Z),环境等待 W → 异常即推送(P0 门禁失败、flaky 率越线、超期缺陷) 4. 发版决策页(发布单的 quality 段) → 所有度量的"汇总结论页"(详见发布管理篇) 5. 复盘输入(缺陷归因/发布复盘/左移成效) → 度量数据是复盘的"事实底座",复盘结论必须引用数据
|
五、落地路线(3 个月)
1 2 3 4 5 6 7 8 9 10 11 12 13
| M1:数据管道(最难的一步) - 缺陷平台/CI/发布平台 API 打通,统一进指标库 - 先上 L2(每日执行状态)——一线马上有感知,信任建立最快
M2:L1 指标 + 防刷分配对 - flaky 率、风险覆盖率、门禁拦截率 - 每对指标同时上(矛和盾一起看) - 周度风险清单自动化
M3:L0 结论化 - 月度质量报告的"显式结论"规则化(好/有风险/差 + 依据) - 管理层第一次看到"结论 + 3 趋势"而不是 20 个数字 - 复盘流程引用度量数据(制度固化)
|
先 L2 后 L0 的原因:度量体系的信用来自"数据和我看到的一致"——一线先用起来发现数据靠谱,上层的结论才有人信。反过来从管理层仪表盘开始,数字对不上一次,整个体系信用破产。
六、度量体系永远不该做的三件事
| 不该做 |
为什么 |
| 用度量排名个人/团队 |
必然刷分 + 藏缺陷 + 拆台(数据不共享),度量考团队机制不考人 |
| 指标超过 20 个 |
没人看得完 = 没人看 = 没有指标。每层 ≤ 7 个,季度审视删一半 |
| 指标口径不公示 |
"这个数怎么算的"答不上来 = 数字没有权威。每个指标有公开公式页 |
七、小结
度量体系三根支柱:分层(管理层看结论、leader 看风险、一线看执行)、防刷分(指标成对、只考趋势、可下钻、自动采集)、有出口(报告/清单/发版决策/复盘,不是孤立仪表盘)。终极检验标准:三个月后问"质量怎么样",回答里每个判断都能指到一条数据,每条数据都能下钻到个案——到不了这一步,再漂亮的仪表盘都是装饰品。