关于 quality-postmortem
quality-postmortem 是面向工程和 QA 团队的质量复盘技能,用于分析线上逃逸缺陷、测试套件健康状况及流程缺口。它强调无责的系统性分析,并要求形成可跟踪的具体改进项。
主要功能
- 01分析线上逃逸缺陷
- 02归纳缺陷重复模式
- 03审查测试套件健康度
- 04制定并跟踪改进项
适用场景
- 01复盘单个线上缺陷
- 02汇总多个缺陷寻找共性
- 03开展季度测试健康检查
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill quality-postmortem安装后在 Claude Code 中输入/quality-postmortem确认已加载。
附带文件references/templates.md
详细介绍
快速导航
| 你遇到的情况…… | 前往 | 模板 |
|---|---|---|
| 有一个逃逸缺陷需要剖析 | 缺陷模式分析 | 逃逸缺陷分析(references/templates.md) |
| 有 10+ 个逃逸缺陷,想寻找规律 | 长期模式汇总 | — |
| 想主动开展季度检查(无事故) | 测试套件健康状况评审 | — |
| 发生 P0/P1 生产事故 | 质量事故复盘模板 | references/templates.md |
| 定期进行迭代/月度评审 | 回顾会议模板 | references/templates.md |
发现问题
先检查项目根目录中的 .agents/qa-project-context.md——其中包含质量目标、风险领域和测试套件详情,可为复盘提供依据。使用其中的信息,并跳过已回答的问题。然后进一步确认:
-
你们是否有定期回顾的节奏? 每个迭代、每月,还是只在事故发生后进行?定期回顾能发现缓慢累积的问题。只在事故后回顾,会让问题模式一直隐藏,直到彻底爆发。
-
是什么触发了这次复盘? 生产事故?逃逸缺陷的模式?感觉测试套件捕获的问题不够多?测试套件退化?触发因素决定复盘重点。
-
有哪些数据可用? 包含严重程度和发现阶段的缺陷跟踪系统?CI 历史记录和通过率?不稳定测试报告?覆盖率趋势?没有数据,复盘就会沦为各执一词的讨论。
-
之前复盘的行动项落实得如何? 是否已完成?是否有跟踪?是否被遗忘?如果过去的行动项都不了了之,团队就会认为复盘无关紧要。再次复盘前,先解决后续跟进问题。
-
哪些人应该参与? 负责受影响区域工作的工程师;负责测试(或未测试)相关内容的 QA;如果影响面向用户,则邀请产品负责人;如果需要系统性变更,则邀请工程经理。参与人数控制在 4-8 人。
-
目前对测试套件健康状况有哪些担忧? 不稳定测试是否增多?执行是否变慢?关键领域是否存在覆盖率缺口?隔离测试是否过时?健康状况评审属于主动复盘——它能预防事故,而非事后响应。
核心原则
1. 无责备意味着着眼于系统
无责备并不意味着“无人负责”。而是指分析关注系统、流程和工具,而非个人表现。“系统为何会让这个缺陷逃逸?”是一个无责备的问题。“开发人员为什么没有编写测试?”则是归责式的问题,会让分析过早终止。开发人员没有编写测试,可能是因为测试框架难以使用、PR 检查清单没有要求、没有结对协作来传递知识,或时间压力让测试显得可有可无。这些都是系统性问题,需要系统性解决方案。
2. 关注模式,而非事故
单个逃逸缺陷只是一个个例。两个月内同一功能领域出现三个逃逸缺陷,才是一个模式。复盘应汇总事故,找出反复出现的主题:相同的根本原因、相同的团队、相同的测试缺口、相同的流水线阶段。模式可以采取行动。单次事故只是在救火。
3. 每次复盘都要产出 1-3 项具体行动项
行动项具备以下要素才算具体:明确的交付物(“为优惠券 API 添加集成测试”)、负责人(“分配给 Alex”)、截止日期(“在第 14 个迭代结束前”)和验证方式(“PR 已合并,测试在 CI 中通过”)。“改进测试”不是行动项。“在 3 月 30 日前为支付服务的边界情况编写 5 个集成测试”才是。
4. 跟踪直至完成
未跟踪的行动项就无法完成。使用团队现有的工作跟踪工具(Jira、Linear、GitHub Issues),并为行动项添加 postmortem-action 或等效标签。在下一次复盘开始时检查完成状态。如果行动项总是不了了之,要么是项目过大(将其拆分),要么是优先级不足(将其列为冲刺承诺)。
5. 用两个指标而不是一个来衡量改进
实施行动项后,衡量问题是否再次发生。如果复盘发现支付测试存在缺口,而行动项是添加集成测试,就要跟踪:是否又有支付错误漏网?没有衡量,复盘就只是仪式,而不是工具。
同时跟踪两个指标:
- 缺陷漏出率(类似错误是否再次出现?)
- 行动项关闭率(行动项中有多少在承诺期限内完成交付?)
关闭率高但漏出率上升,说明团队确实在做事,但做的不是该做的事。关闭率低,说明复盘只是在走过场。现代事件响应平台(incident.io、Rootly、FireHydrant)会原生跟踪行动项的后续进展——负责人、到期日期、完成状态——因此,在构建仪表板之前,先用已有数据计算这两个指标。
6. 由 AI 起草时间线,由人负责判断
如果团队使用 AI SRE 工具(Rootly AI SRE、incident.io 的 AI SRE / 自动起草的事后复盘),可以让它根据日志和跟踪数据起草事件时间线,并提出可能的根本原因。然后,由一位指定的无责 RCA 负责人——不同于负责管理响应的事件指挥官——进行 5 Whys 分析、选定真正的根本原因并编写行动项。AI 擅长从嘈杂的数据中找出关联,但不擅长判断哪些因素真正重要。应将 AI 输出视为初稿,而不是结论。若只需低成本地起草时间线,Sonnet 4.6 就足够;将更强大的模型留给因果关系不明确的情况。
Bug 模式分析
对漏网缺陷进行分类
Bug 上线后,从三个维度对其进行分类,以找出预防机会。单个 Bug 分析表(Escaped Bug Analysis)位于 references/templates.md。
维度 1:根本原因类别
| 类别 | 描述 | 示例 |
|---|---|---|
| 逻辑错误 | 业务逻辑不正确或不完整 | 特殊货币情况下未应用折扣 |
| 集成失败 | 两个组件无法正确通信 | API 返回的格式与前端预期不同 |
| 数据问题 | 数据形态异常、值为 null、编码问题 | 用户姓名中包含表情符号,导致 CSV 导出失败 |
| 竞态条件 | 依赖时序的行为 | 两笔并发结账超卖了最后一件商品 |
| 配置问题 | 环境特定设置错误 | 功能开关在预发布环境中启用,在生产环境中禁用 |
| 回归 | 之前正常的行为被破坏 | 重构移除了 null 检查,旧 Bug 再次出现 |
| 需求缺失 | 未规定行为,产品规范存在缺口 | 未处理过期 OAuth 令牌的错误 |
| 性能问题 | 功能正常,但负载下速度过慢 | 记录超过 10 万条时搜索超时 |
维度 2:哪个测试级别本应发现它
| 级别 | 可捕获的问题 | 如果缺陷漏过此级别 |
|---|---|---|
| 单元测试 | 逻辑错误、边界情况、边界条件 | 是否有测试但漏掉了边界情况?还是根本没有测试? |
| 集成测试 | API 契约、数据流、服务交互 | 是否有集成测试?是否覆盖了错误响应? |
| 端到端测试 | 用户流程故障、UI 状态管理 | 是否覆盖了这条关键路径?是否测试了这一特定场景? |
| 手动/探索性测试 | 视觉问题、可用性问题、不常见的工作流 | 是否执行了探索性测试?该区域是否在测试范围内? |
| 监控 | 性能下降、错误率激增 | 是否配置了警报?阈值是否正确? |
维度 3:预防机会
| 机会 | 行动 | 示例 |
|---|---|---|
| 添加测试 | 在合适的层级编写测试 | 为货币舍入边界情况添加单元测试 |
| 改进现有测试 | 现有测试的覆盖范围过窄 | 扩展结账 E2E 测试,涵盖优惠券和国际货币 |
| 添加质量门禁 | CI 检查本可以发现问题 | 在 CI 中添加 API 响应的架构验证 |
| 改进需求 | 规范含糊不清或不完整 | 在故事模板中添加错误状态的验收标准 |
| 添加监控 | 即使无法预防,也要尽早发现 | 为支付端点错误率超过 1% 添加告警 |
| 培训/流程 | 知识缺口或流程缺口 | 开展一次关于可空字段防御性编码的培训 |
随时间汇总模式
分析 10 个以上逃逸缺陷后,寻找模式:
Escaped Bug Summary: [Q1 2026]
═══════════════════════════════
Total escaped bugs: 14
By root cause:
Logic error: 5 (36%) ← unit tests needed
Integration failure: 4 (29%) ← API contract tests needed
Data issue: 3 (21%) ← input validation gaps
Configuration: 2 (14%) ← env parity issues
By area:
Checkout: 6 (43%) ← highest risk, needs investment
User management: 4 (29%)
Reporting: 2 (14%)
Settings: 2 (14%)
By should-catch level:
Unit: 5 (36%) ← developers not testing edge cases
Integration: 4 (29%) ← missing integration test layer
E2E: 3 (21%)
Monitoring: 2 (14%)
Top action themes:
1. Add integration tests for checkout API (covers 4 of 14 bugs)
2. Mandate unit tests for all calculation/validation logic (covers 5 of 14)
3. Add currency and encoding edge cases to test data fixtures (covers 3 of 14)
这项汇总能揭示在哪些方面投入回报最高:修复一个系统性问题(结账集成测试)就能预防所有逃逸缺陷中的 29%。多个季度反复出现的模式应纳入 test-strategy 文档,而不应只列入下一个冲刺的行动项——应将其提升为策略,让策略反映缺陷实际逃逸的环节。
测试套件健康状况审查
针对测试套件本身进行主动复盘。每季度进行一次,或在出现问题迹象时进行。
不稳定测试趋势
Flaky Test Trend Review
═══════════════════════
Current flaky rate: _____ % (target: <2%)
Trend (last 3 months):
Month 1: _____ %
Month 2: _____ %
Month 3: _____ %
Direction: [ ] Improving [ ] Stable [ ] Worsening
Top 5 flakiest tests (by failure count):
1. _____________________ — _____ failures — root cause: _____
2. _____________________ — _____ failures — root cause: _____
3. _____________________ — _____ failures — root cause: _____
4. _____________________ — _____ failures — root cause: _____
5. _____________________ — _____ failures — root cause: _____
Quarantine:
Tests in quarantine: _____ count
Oldest quarantine: _____ days (target: <14)
Quarantine resolved this month: _____ count
执行时间趋势
记录当前完整测试套件的运行时长、近 3 个月的趋势,以及最慢的 5 个测试。如果时长不断增加,请检查:哪些测试可以移至夜间运行,哪些串行阶段可以并行化,哪些测试数据准备流程较慢(改用 API 而不是 UI),哪些大型测试文件需要拆分以更好地分配分片。
覆盖率缺口审查
跟踪整体覆盖率(行/分支)、覆盖不足的关键路径(支付、身份验证、数据导出应达到 90% 以上)、近期更改但未更新测试的代码(将 git log --since="30 days ago" 与覆盖率报告交叉比对),以及未进行 E2E 覆盖就已发布的功能。
已禁用/已跳过测试清单
按跳过/禁用时间和原因审查所有测试。跳过时间不足 1 周的测试很可能仍在开发中。跳过 1–4 周的测试需要创建工单并制定时间表。跳过 1–3 个月的测试已经逾期——应修复或删除。跳过超过 3 个月的测试应删除——它们永远不会被修复。对每个测试,选择修复并取消跳过、删除(已过时),或移至隔离区并附上工单链接。
流程改进周期
改进冲刺
每个冲刺固定投入一部分资源(容量的 10–15%)用于质量改进,工作内容来自复盘行动项和健康状况审查发现的问题。
结构:
1. IDENTIFY — Top 3 pain points from latest retro/postmortem
2. ROOT CAUSE — 5 Whys analysis for the #1 pain point
3. PROPOSE — Solution with effort estimate (S/M/L)
4. IMPLEMENT — One improvement per sprint (start small)
5. MEASURE — Did the metric improve? By how much?
6. ITERATE — If not improved, dig deeper. If improved, tackle #2.
5 个为什么根因分析
“5 个为什么”方法通过层层追问表面症状,揭示系统性原因。关键在于始终追问“为什么”,直到找到流程、系统或结构层面的原因,而不是归咎于个人行为。
示例:支付缺陷逃逸到生产环境
Problem: Users were charged twice for a single purchase.
Why 1: The payment API was called twice on form submit.
Why 2: The submit button was not disabled after the first click.
Why 3: The frontend developer did not implement button disabling.
Why 4: The acceptance criteria did not mention double-submit prevention.
Why 5: The story refinement process does not include edge case review
for payment-related stories.
Root cause: Process gap — payment stories are not reviewed for transaction
safety edge cases before development begins.
Action: Add a "Payment Safety Checklist" to the story template for any
story touching payment flows. Checklist includes: idempotency,
double-submit prevention, partial failure handling, timeout behavior.
Owner: [Product Manager] — Due: [Next sprint]
5 个为什么的准则:
- 当找到团队可以改变的因素(流程、工具、结构)时就停止。追问“为什么预算有限?”就过头了。
- 因果链可能分支——一个症状可能有多个促成因素。沿着影响最大的分支继续追查。
- 用证据而非假设验证每个“为什么”。“开发者没有编写测试”——这是真的吗?检查 PR。也许测试已经存在,只是覆盖不足。
- 如果最终将“人为错误”确定为根因,说明追查还不够深入。人都会犯错。系统应让错误难以发生或容易被发现。
提出并估算解决方案的工作量
针对每个根因,提出 1–3 个不同工作量级别的解决方案。以下是针对反复出现的不稳定测试问题的示例:
Root Cause: E2E tests fail intermittently on async-loaded content
Solution A (Small — 1 day):
Replace fixed waitForTimeout calls with explicit wait-for-condition
assertions in the 5 flakiest specs.
+ Quick to implement, kills the most common flake source
− Manual, one spec at a time; new flakes can creep back in
Solution B (Medium — 1 sprint):
Solution A across the suite + add a flaky-test detector to CI that
reruns failures once and tags any test that passes on retry.
+ Automated detection, surfaces flakes before they erode trust
− Requires CI config change; reruns add pipeline time
Solution C (Large — 2 sprints):
Solution B + auto-quarantine tagged tests and route them to an
owner-assigned backlog with a 14-day fix-or-delete SLA.
+ Self-healing trust in the green build; flakes can't block releases silently
− Needs quarantine infrastructure and ownership process buy-in
Recommendation: Start with A immediately, implement B this sprint,
plan C for next quarter as strategic work.
事后复盘与回顾模板
references/templates.md 中提供了两种篇幅较长、可直接复制粘贴的格式:
- 质量事件事后复盘模板 — 适用于由代码变更导致的 P0/P1 生产环境 Bug、数据丢失、安全问题或服务中断。包含摘要、严重程度/影响、UTC 时间线表、根本原因、5 个为什么、已有/缺失的测试、检测情况、即时/短期/长期行动项表以及经验教训。
- 回顾会议模板 — 适用于定期开展的冲刺/月度质量回顾:包含 7 个环节、时长 30-60 分钟的议程(回顾上次行动项 → 回顾数据 → 做得好的方面 → 待改进的方面 → 讨论根本原因 → 新行动项 → 总结),以及主持人备注。
两种模板都会先回顾上次回顾会议的行动项——这个闭环机制用于落实责任;若没有它,行动项就会悄无声息地消失。
反模式
归咎于个人的事后复盘
只关注谁犯了错,而不关注是什么系统因素让错误进入了生产环境。指责会制造恐惧,恐惧会让人隐瞒,隐瞒会引发更大的事件。当问题是“这个 Bug 是谁写的?”时,人们会学着回避暴露问题;当问题是“哪个流程缺口导致了这个问题?”时,人们会学着改进流程。
没有行动项的事后复盘
讨论让人畅快,也增进了理解,却没有带来任何改变。如果会议结束时没有明确指派具体的行动项,同样的问题就会再次发生。更糟的是,团队会认为事后复盘只是疗愈情绪的谈话,而不是改进工具。
有行动项却没有后续跟进
提出行动项,将其放入待办列表,却从未排定优先级。这比没有行动项更糟,因为它营造了正在改进的假象。如果事后复盘中的行动项在 2 个冲刺内没有完成,就应升级处理。行动项会因一些可预见的原因而不了了之——在归咎于“我们忘了”之前,请对照此清单审查行动项的关闭率:
- 没有负责人。 指派给团队而非个人的行动项,就会变成谁都不负责的工作。改进方法:指派给一位有足够背景信息、能够着手处理的具体人员。
- 没有截止日期。 “尽快”不是日期。改进方法:指定具体的冲刺或日历日期。
- 范围太大。 “重构测试框架”无法在一个冲刺内完成。改进方法:拆分成每项都能通过单个 PR 完成的任务。
- 下次回顾开始时没有检查。 没有强制跟进,行动项就会悄无声息地消失。改进方法:在日历中固定安排一个时段,让每次回顾都以闭环检查开始。
- 没有关联指标。 如果完成行动项不会改变一个明确的数值,你就无法判断它是否有效。
反模式的替代做法:每次回顾都用 5 分钟检查“上次行动项”。将每项标记为“已完成”/“进行中”(并注明当前预计完成时间)/“已取消”(并说明原因)。
只在发生事件后才做事后复盘
等到生产环境发生故障后才开展质量审查。主动开展健康检查(测试套件健康状况、覆盖率趋势、不稳定测试清单)可以预防事件。每月开展主动审查。针对事件的事后复盘是对主动审查节奏的补充,而非替代。
根本原因分析过早停止
“开发人员没有编写测试”不是根本原因,而是一个症状。他们为什么没有编写测试?是框架难用吗?是没有时间吗?是没有相关要求吗?是没有结对协作或代码审查吗?止步于个人层面会阻碍系统性改进。
含糊的行动项
“提高测试覆盖率”和“部署时更加谨慎”都不算行动项,因为无法跟踪、衡量或验证。对比:“为支付 Webhook 处理添加集成测试,覆盖成功、失败和超时场景。负责人:Alex。截止时间:Sprint 14。验证方式:PR 已合并,CI 中新增的 3 项集成测试均通过。”
无数据复盘
基于感觉和观点,而非数据开展质量复盘。“感觉最近的 Bug 变多了”可能属实,也可能是近因偏差。查看数据:逃逸 Bug 数量真的在增加吗?Bug 集中在哪些方面?没有数据,团队解决的就会是最引人关注的问题,而不是最重要的问题。
验证
产出物是书面事后分析报告,以及其中已跟踪并闭环的行动项。证明它已落地——先做最小检查。
# Every action item became a real, owned, dated ticket — not a doc bullet.
# (gh example; swap for `jira issue list` / Linear API as appropriate)
gh issue list --label postmortem-action --json number,title,assignees,milestone \
| jq '[.[] | select(.assignees == [] or .milestone == null)]'
# Expect: [] (empty). Any item missing an owner or due milestone is not done.
# The escaped defect's timeline is reconstructable from evidence, not memory.
git log --since="<introduced-date>" --until="<detected-date>" --oneline -- <affected/path>
# Expect: the introducing commit is in this range and named in the postmortem.
# The fix/regression test the action item promised actually exists and passes.
git log --grep="<INCIDENT-ID>" --oneline # the fix commit references the incident
<your test runner> <new regression test path> # exits 0
然后通过阅读确认:5 Whys 最终指向流程/工具/结构层面的原因(而不是“开发人员没有编写测试”),并且记录了行动项闭环率和逃逸缺陷率——不能只记录其中一项。
完成标准
- 根据提交历史和 Bug 跟踪器中的佐证,重建逃逸缺陷时间线(引入、发布、检测、解决)。
- 完成 5 Whys 根因分析,并将分析追溯到系统性原因(流程/工具/结构),而不是“开发人员没有编写测试”。
- 找出测试缺口,并将其映射到具体的覆盖缺失(缺少测试类型、缺少场景或缺少覆盖领域)。
- 为行动项指定明确的负责人和截止日期,并将其添加到团队的工作跟踪器中,附上事后分析标签。
- 以书面摘要形式与团队分享发现,不要将其仅限于 QA 团队内部,或放在私人文档中后无人问津。
- 将行动项闭环率与逃逸缺陷率一并跟踪(两项指标都要有,不能只记录一项);对于事件事后分析,这两项都可以从事件平台原生的后续跟进跟踪中推导得出。
- 如果正在使用 AI SRE 工具,则应将 AI 起草的时间线和候选根因记录为输入,并由指定的、秉持无责原则的 RCA 负责人(而非事件指挥官)审核并签署人工编写的 5 Whys 和行动项。
相关技能
- qa-metrics — 提供事后分析所需的数据(缺陷逃逸率、测试不稳定率、覆盖率趋势),以便分析并采取行动。用于持续监控的仪表板;使用此技能开展分析会议。
- test-reliability — 对不稳定测试进行分类并管理隔离,这些工作会为测试套件健康状况评审提供依据。
- test-strategy — 当事后分析揭示出连续多个季度反复出现的系统性缺口时,应更新测试策略文档。
- shift-left-testing — 许多事后分析行动项都属于左移实践:更早测试、改进需求、开发/QA 搭档协作。
- release-readiness — 应根据事后分析发现更新质量门禁和发布标准;用于实时评估是否放行,不用于回顾性分析。
参考文件(位于 references/ 中)
- templates.md — 可直接复制粘贴的质量事件事后分析模板、复盘会议模板及主持人说明,以及针对单个 Bug 的逃逸 Bug 分析工作表。