问题修复
逃逸缺陷与测试套件健康复盘:用无指责复盘定位系统性质量缺口并…
当生产环境逃逸出 bug、发生 P0/P1 质量事故、测试套件拦截力下降,或需要周期性(每 sprint/每月/每季度)检查质量流程健康度时,用结构化无指责复盘找出系统性根因并落地 1-3 条具名、有截止日期、可验证的行动项。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
逃逸缺陷与测试套件健康复盘:用无指责复盘通用
解决思路
- 先读项目根目录的 `.agents/qa-project-context.md`,取出其中已有的质量目标、风险区域和测试套件细节作为复盘锚点,凡是那里已回答的问题直接跳过,不再重复询问。
- 开跑前澄清六件事:1) 是否有固定的回顾节奏(每 sprint / 每月 / 仅事故后)——仅事故后的节奏会漏掉慢性问题;2) 本次复盘的触发原因(生产事故 / 逃逸 bug 模式 / 感觉测试套件拦不住 / 测试套件退化),触发原因决定聚焦点;3) 有哪些可用数据(带严重级别和发现阶段的 bug 追踪、CI 通过率历史、flaky 测试报告、覆盖率趋势),没有数据复盘会退化成意见会;4) 上一次复盘的行动项执行情况(完成、被跟踪还是被遗忘)——若历史行动项长期被放弃,说明团队已学会「复盘不重要」,先修好跟进机制再开新复盘;5) 谁参加(受影响区域的工程师、测试或未测试该处的 QA、影响用户时加产品负责人、需要系统性变更时加工程经理),人数控制在 4-8 人;6) 当前测试套件健康隐患(flaky 上升、执行变慢、关键区域覆盖缺口、quarantine 过期)。
- 坚持无指责=系统性:分析聚焦流程、系统和工具,而不是个人表现;问「系统为什么允许这个缺陷逃逸」,而不是「开发者为什么没写测试」。后者会过早终止分析——开发者没写测试的真实原因可能是框架难用、PR 清单没要求、没有结对传承知识、或时间压力让它显得可选,这些都是有系统性解法的系统性问题。
- 聚焦模式而非单个事件:单个逃逸 bug 只是轶事,两个月内同一功能区出现三个逃逸 bug 才是模式。把多次事故聚合起来找重复主题:同一根因、同一团队、同一测试缺口、同一流水线阶段。模式才可执行,单个事件只是救火。
- 每次复盘只产出 1-3 条具体行动项。具体=有明确交付物(「为优惠券 API 加集成测试」)、有具名负责人(「分配给 Alex」)、有截止日期(「sprint 14 结束前」)、有验证方式(「PR 合并,CI 中测试通过」)。「改进测试」不是行动项,「3 月 30 日前为支付服务边界场景写 5 个集成测试」才是。
- 把行动项跟踪到完成:写进团队现有的工作追踪器(Jira、Linear、GitHub Issues),打上标签(如 `postmortem-action` 或等价物),并在下一次复盘开头检查完成状态。如果行动项持续被放弃,要么是条目太大(拆小),要么是没被排进优先级(变成 sprint 承诺)。
- 用两个指标而不是一个来衡量改进:缺陷逃逸率(同类 bug 是否重现)+行动项关闭率(承诺窗口内交付的比例)。关闭率高但逃逸率上升,说明团队在做工但做的是错的事;关闭率低,说明复盘只是作秀。优先从现有事故响应平台(incident.io、Rootly、FireHydrant)原生的跟进跟踪里取数(负责人、截止日期、完成状态),拿到两个数字之后再考虑自建 dashboard。
- 让 AI 起草时间线,由人负责判断:若团队使用 AI SRE 工具(Rootly AI SRE、incident.io 的 AI SRE / 自动起草复盘),让它先根据日志和 trace 起草事故时间线并给出候选根因;再由一名具名的「无指责 RCA 负责人」(与负责指挥响应的事故指挥官不是同一人)主持 5 Whys、选定真正的根因、撰写行动项。AI 擅长在噪声数据里做关联,不擅长判断什么才是关键。把 AI 输出当作起手稿而非结论。便宜的时间线起草用 Sonnet 4.6 足够,因果不明时才换更重的模型。
- 对逃逸缺陷按三个维度分类:维度一「根因类别」——逻辑错误、集成失败、数据问题(数据形状/空值/编码)、竞态条件、配置、回归、需求缺失、性能;维度二「本应由哪一测试层级捕获」——单元(逻辑、边界、边界条件)、集成(API 契约、数据流、服务交互)、E2E(用户旅程、UI 状态)、手工/探索(视觉、可用性、异常流程)、监控(性能退化、错误率飙升),并追问为什么没拦住;维度三「预防机会」——新增测试、改进过窄的现有测试、加 CI 质量门(如 API 响应 schema 校验)、改进需求(把验收标准写进故事模板)、加监控、培训/流程改进。单个 bug 用 `references/templates.md` 中的 Escaped Bug Analysis 工作表。
- 分析完 10+ 个逃逸 bug 后做聚合统计:按根因、按功能区域(如 Checkout、User management、Reporting、Settings)、按应捕获层级分别统计数量和占比,列出 top 行动主题,找出投入回报最高的系统性修复(例如「为 checkout API 补集成测试」可覆盖 29% 的逃逸 bug)。
- 跨多个季度反复出现的模式要提升写入 `test-strategy` 文档,而不只是留在下一个 sprint 的行动项里,让测试策略反映缺陷真正从哪里逃逸出来。
- 每季度或出现症状时做一次测试套件健康评审(主动式复盘):跟踪 flaky 测试趋势——当前 flaky 率(目标 <2%)、近 3 个月趋势、方向(改善/稳定/恶化)、失败次数最多的 top 5 flaky 测试及其根因、quarantine 中的测试数量、最老 quarantine 天数(目标 <14 天)、本月解决的 quarantine 数量。
- 跟踪执行时长趋势:记录当前全量套件时长、3 个月趋势、最慢的 5 个测试。若时长在上升,检查:能否把测试移到 nightly、串行阶段能否并行、测试数据准备是否过慢(用 API 代替 UI)、大测试文件是否需要拆分为更好的分片。
- 做覆盖率缺口评审:跟踪总体覆盖率(行/分支)、关键路径覆盖率(支付、认证、数据导出应达 90%+)、最近改动但未同步更新测试的代码(用 `git log --since="30 days ago"` 对照覆盖率报告)、以及无 E2E 覆盖就上线的功能。
- 盘点被禁用/跳过的测试:按年龄和原因审计。跳过 <1 周大概率还在进行中;跳过 1-4 周需要建工单和时间线;跳过 1-3 个月属于逾期,修掉或删除;跳过 >3 个月应直接删除(永远不会被修)。每条要么修复并取消跳过,要么删除(已过时),要么移入 quarantine 并附工单链接。
- 每个 sprint 拿出固定 10-15% 产能做质量改进冲刺,来源是复盘行动项和健康评审发现。流程:IDENTIFY(从最新回顾/复盘中选前三大痛点)→ ROOT CAUSE(对第一痛点做 5 Whys)→ PROPOSE(给出带工作量估算的方案 S/M/L)→ IMPLEMENT(每个 sprint 只做一个改进,从小处开始)→ MEASURE(指标是否改善、改善了多少)→ ITERATE(未改善就继续深挖,改善了就处理第二痛点)。
- 执行 5 Whys 时遵守纪律:每个「why」都用证据验证而不是靠假设(「开发者没写测试」是真的吗?去查 PR,也许测试存在但不够充分);因果链可以分叉,跟随影响最大的分支;当问到团队可以改变的东西(流程、工具、结构)时就停止,继续问「为什么预算有限」就过头了;如果根因停在「人为失误」,说明还没有问够——人会犯错,系统应让错误难以发生或能被检测到。参考示例:重复扣款 → 提交按钮未禁用 → 开发者未实现禁用 → 验收标准未提双击提交 → 需求细化流程不审查支付类故事的边界场景,根因为「流程缺口」,行动项是给触及支付流程的故事模板加一份「支付安全清单」(幂等性、防重复提交、部分失败处理、超时行为),指定负责人和截止日期。
- 针对每个根因提出 1-3 个不同工作量级别的方案,逐个列出利弊并给出推荐。示例(E2E 异步内容导致 flaky):方案 A(Small,1 天)把 5 个最 flaky spec 中的固定 `waitForTimeout` 换成显式等待条件断言,快但手工、新 flake 会回流;方案 B(Medium,1 sprint)A 铺满全套件+在 CI 加 flaky 检测器,失败重跑一次并给「重跑才过」的测试打标签,自动但需要改 CI 配置、增加流水线时间;方案 C(Large,2 sprint)B+自动 quarantine 打标签测试并路由到有负责人、14 天「修或删」SLA 的待办,需要 quarantine 基础设施和 ownership 流程支持。推荐:立刻做 A,本 sprint 做 B,下季度规划 C 作为战略工作。
- 质量事故(P0/P1 生产 bug、数据丢失、安全问题或由代码变更导致的中断)使用 `references/templates.md` 中的 Postmortem Template:摘要、严重度/影响、UTC 时间线表、根因、5 Whys、当时有哪些测试/缺失哪些测试、检测方式、立即/短期/长期行动表、经验教训。
- 周期性 sprint/月度质量回顾使用 Retro Meeting Template:7 段、30-60 分钟议程(上次行动项回顾 → 数据回顾 → 做得好的 → 需改进的 → 根因讨论 → 新行动项 → 收尾)加主持人笔记。两个模板都以回顾上次回顾的行动项开场——这个闭环就是问责机制,没有它条目会无声消失。
- 避免「无指责变成无人负责」「复盘没有行动项」「行动项无人跟进」。行动项死亡有可预测的原因,先按清单自查再怪「我们忘了」:没有负责人(分给团队=没人负责,改成具名且上下文足够的人)、没有截止日期(「很快」不是日期,改成具体 sprint 或日历日期)、范围太大(「重构测试框架」无法在一个 sprint 落地,拆成每个不超过一个 PR 的条目)、下次回顾开头不复查(设一个固定日历时段强制闭环)、没有绑定指标(如果完成它不能推动一个你能说出口的数字,就无法判断是否有效)。
- 每次回顾开头用 5 分钟做「上次行动项」复查,逐条标记 Done / In Progress(附当前 ETA)/ Dropped(附原因)。
- 不要只在事故后才复盘:主动健康评审(测试套件健康、覆盖率趋势、flaky 测试盘点)用来预防事故,至少每月做一次;反应式的事故复盘是补充,不是替代。
- 避免根因分析过早停止(「开发者没写测试」是症状不是根因)、避免模糊行动项(「提高测试覆盖率」「部署时更小心」无法跟踪/度量/验证)、避免无数据回顾(凭感觉说「最近 bug 变多了」可能是近因偏差,先查数据:逃逸 bug 数是否真的在涨、bug 集中在哪;没有数据团队只会解决最吵的问题而不是最重要的问题)。
- 用命令验证行动项真的落地了,先做最小的检查:`gh issue list --label postmortem-action --json number,title,assignees,milestone | jq '[.[] | select(.assignees == [] or .milestone == null)]'`,期望输出 `[]`;任何缺负责人或缺截止里程碑的条目都算未完成(Jira 用户换成 `jira issue list`,Linear 用户换成对应 API)。
- 验证逃逸缺陷的时间线可由证据而非记忆重建:`git log --since="<introduced-date>" --until="<detected-date>" --oneline -- <affected/path>`,期望引入提交落在该区间并被写进复盘文档。
- 验证行动项承诺的修复/回归测试确实存在且通过:`git log --grep="<INCIDENT-ID>" --oneline` 确认修复提交引用了事故,再运行 `<your test runner> <new regression test path>` 期望退出码为 0。
- 最后阅读确认:5 Whys 停在流程/工具/结构类原因(而不是「开发者没写测试」),并且行动项关闭率和逃逸缺陷率两个数字都被记录,而不是只记一个。完成标准还包括:逃逸缺陷时间线(引入、发布、发现、解决)已用提交历史和 bug 追踪的证据重建;测试缺口已映射到具体覆盖空洞(缺哪种测试类型、哪个场景或哪个区域);行动项已带具名负责人和截止日期并打上复盘标签写入工作追踪器;结论以书面摘要分享给全团队,而不是困在 QA 或私有文档里;若在用 AI SRE 工具,AI 起草的时间线和候选根因已作为输入记录,且由具名的无指责 RCA 负责人(不是事故指挥官)签署确认了人工撰写的 5 Whys 和行动项。
适用边界 · 注意事项
- 不用于上线的 go/no-go 决策——那是 release-readiness 的职责。
- 不用于构建持续运行的指标看板——那是 qa-metrics 的职责;本技能只负责分析会。
- 不用于审查现有测试代码的质量——那是 ai-qa-review 的职责。
- 如果历史复盘的行动项长期被放弃,先修好跟进机制再开新的复盘,否则只是重复制造「复盘不重要」的信号。