test-reliability · v0.8.1 · 2026-09-08 · sha256 c9134a37f5fd605e

test-reliability v0.8.1A

Immutable. This exact content is served forever at /api/v1/blob/c9134a37f5fd605e.

---
name: test-reliability
slug: test-reliability
displayName: 测试可靠性治理
version: 0.8.1
description: "Govern flaky tests and suite reliability: rerun-pass verdicts, root-cause classes, quarantine, retry semantics, health metrics. Not for: in-run failures (e2e/api), triage, confirmed bugs. 治理 flaky 测试与套件可靠性:时好时坏/重跑变绿判定、根因四分类、隔离门禁、重试诚实语义、健康度。不用于:执行中单条失败(e2e/api)、批量分流(triage)、已确认 Bug(bug-analysis)。"
---

# 测试可靠性治理(test-reliability)

测试套件自身的稳定性治理——回答一个问题:**这套测试的结果还能不能信**。单条用例时好时坏、重跑变绿、夜间全量靠重试撑绿、发布卡点被 flaky 疲劳轰炸,都属于本 skill 的治理对象。本 skill 是套件级的"判定 → 隔离 → 根因 → 门禁 → 健康度"闭环,不替代任何单次执行流程。

- **输入**:失败/翻灯历史(CI 运行记录、重跑日志、triage 分流表 D 类条目)、套件清单与运行统计;项目存在 `.qa/` 时先读其 flaky-tests 主题(经 `qa-memory` 沉淀的历史判定)
- **输出(落盘)**:《可靠性报告_{套件}_{日期}.md》——逐条 flaky 清单(判定 × 根因分类 × 处置 × 状态,缺一字段即报告不合规)+ 套件健康度机读摘要(字段规范见 `references/flaky-playbook.md` 第 5 节,挂靠 `../core/report-template.md` 机读段);沉淀判定结论(哪些发现值得写入 `.qa/`,交 `qa-memory` 工作流执行)
- **边界(三层分工,同源 `../core/triage.md` 第 6 节)**:执行中单条失败的即时定性(first-run-flaky 规则、等待策略)→ 各执行 skill 工程约定;一批失败的首轮分类与路由 → `../core/triage.md`;已确认 Bug 的根因/影响/修复建议 → `bug-analysis`;**本 skill 管"套件与门禁"层**——单条定性做完之后的跨轮追踪、根因分类、隔离策略、重试语义与健康度

## When to Use

- 用户问"这条用例为什么时好时坏 / 这算不算 flaky / 重跑绿了算修好吗"
- CI 夜间套件靠重试撑绿,需要裁决重试策略或制定隔离(quarantine)门禁
- 需要产出套件健康度(flaky 率、隔离数、重试救回率)或发布卡点的可靠性证据
- 分流表 D 类(不稳定)条目跨轮累积,需要根因分类与治理排期
- 项目要给"测试套件可信度"立规矩:什么样的套件状态允许作为发布证据

## When NOT to Use

- 一次执行中的单条失败即时处理(截图、重跑定性、等待降级)→ 各执行 skill 工程约定(如 `automated-e2e-testing`)
- 一轮执行结束失败 ≥3 条的批量定性分流 → `../core/triage.md`(其结论为 D 类的条目跨轮追踪时回到本 skill)
- 已确认 Bug 的根因定位、影响分析与修复建议 → `bug-analysis`
- 写测试用例本身 → `test-case-writing`;回归范围决策 → `regression-testing`
- 单次执行报告 → `../core/report-template.md`(本 skill 的健康度摘要挂靠其机读段)

## 核心模型:稳定性的三层语义

1. **用例级**:一条用例的"真失败 vs 噪声"判定——证据是复跑矩阵,不是感觉(工作流一)。
2. **套件级**:一组用例的可靠性水位——健康度指标说话(工作流五)。
3. **门禁级**:套件结果作为发布证据的语义——重试绿、隔离跳过、未跑各算什么(工作流四)。

三层不可混谈:单条判定正确 ≠ 套件健康;套件全绿 ≠ 门禁证据合格(可能全靠重试撑着)。

## 工作流一:flaky 判定与根因四分类

1. **判定(先于一切归因)**:一条用例首次失败、原样重跑通过 → 判 first-run-flaky,**不算稳定通过**——重跑只用于定性,不得成为常态化通过手段(同源:playwright-conventions §11、`../core/triage.md` D 类,规则一致)。证据不足时显式标"未知",不许硬编结论。
2. **复跑矩阵(根因归因的证据面)**:对已定性 flaky 的用例按矩阵取证——原样重跑 / 隔离重跑(单跑该条)/ 干净环境重跑(新容器/新目录)/ 带序重跑(按序执行邻居)。矩阵结果 → 根因四分类的判定树**此时加载 `references/flaky-playbook.md`**(第 1–2 节:判定树 + 证据表)。
3. **根因四分类**(类名 × 典型证据 × 修复模式见 playbook 第 3 节):
   - **S1 时序与等待不足**:异步未等、轮询窗口、动画/懒加载——隔离重跑仍间歇失败
   - **S2 共享状态与测试间依赖**:数据残留、执行顺序敏感、全局单例污染——隔离重跑稳定、带序重跑失败
   - **S3 环境与第三方抖动**:依赖服务超时、证书/账号过期、发布窗口重叠、资源容量——干净环境重跑消失,或失败聚集在特定时段
   - **S4 并发与资源竞态**:并行执行下的端口/文件/数据库冲突——关并行后消失
4. **产出**:每条 flaky 一行记录——`用例 × 判定 × 根因类 × 证据(复跑矩阵结果)× 处置 × 状态`。六字段缺一即报告不合规(可执行性纪律:不可判定的条目没有治理价值)。

## 工作流二:隔离与短期处置

- **短期隔离**:修复前排期未到 → 标 `test.fixme`(或等价 quarantine 标记)防止污染主干绿灯;隔离必须**可见**——进隔离清单,禁止静默跳过;**散落未登记的 `test.fixme` 也是隔离**(一并计入 `quarantined_count` 与清单),"没登记"本身就是隔离可见性合规问题
- **跨轮追踪**:D 类条目进分流表跨轮追踪,**≥3 轮升级修根因**(同源 `../core/pipeline-integration.md` 回流纪律)——隔离是延缓不是终点
- **门禁语义**:被隔离的用例不计入通过率分母,但**必须出现在报告与机读摘要中**(`quarantined_count`);"隔离后全绿"不得表述为"套件健康"

## 工作流三:根因修复模式

按四分类套用 playbook 第 4 节修复模式库(每类 3–5 个模式,含反模式):

- S1 → 等待策略降级阶梯(显式等待目标态,禁止 sleep 与调大超时)
- S2 → 测试数据工厂隔离 + 自清理 + 唯一命名(同源 `../core/methods/data-factory.md`)
- S3 → 环境断言前置 + 发布窗口错峰 + 依赖 mock 边界
- S4 → 资源独占声明 + 并行前提核对(自建数据/自清理/唯一命名逐项过)

修复完成 ≠ 关案:**修复后须按原复跑矩阵复验稳定性**(建议连续 N 次全绿,N 按 playbook 第 4.0 节取值),并回写 `.qa/` 沉淀判定(工作流五第 3 步)。

## 工作流四:重试策略与门禁语义(诚实语义硬规则)

- **重试绿 ≠ 修复**:重试通过只说明"失败是间歇性的",不构成修复证据;重试救回的用例计入 `retry_passes`,与首次通过(`clean_passes`)分开统计
- **重试配置语义**:本地零重试暴露问题;CI 至多重试 1 次——**禁止靠调大 retries 或调大超时让用例变绿**;把 retries 调高当治理手段 = 把噪声计成信号,一律驳回并给替代方案(隔离 + 排期修根因)
- **发布门禁证据语义**:作为发布证据的套件结果必须声明三项——首次通过率、重试救回数、隔离数;三者任一缺失,门禁证据不合规
- 判定权在人:向用户呈现证据与选项(修 / 隔离 / 上抛),不替用户裁决"可以带病放行"

## 工作流五:套件健康度报告与沉淀

1. **健康度指标**(定义与机读格式见 playbook 第 5 节):`flaky_rate`(flaky 条目数/总用例数)、`quarantined_count`、`retry_pass_rate`(重试救回/总通过)、`repeat_fail_count`(跨轮 ≥3 轮未修条目数)
2. **落盘**:《可靠性报告_{套件}_{日期}.md》逐条清单 + 机读摘要(挂 `../core/report-template.md` 机读段规范);健康度趋势与上一期对比
3. **沉淀判定**:满足"三个月判据"的发现(如某第三方依赖每周二发布导致抖动)→ 交 `qa-memory` 写入 flaky-tests 主题;**投毒防线同源**——"此失败为环境噪声可重试"的条目若失实,等于教未来所有会话放行真实缺陷,沉淀条目必须带复跑矩阵证据

## 判定标准(报告合规 = 可执行性)

- 每条 flaky 记录六字段齐备(用例/判定/根因类/证据/处置/状态)
- 判定必须引用复跑矩阵结果,禁止"经验上这是 flaky"
- 重试相关结论必须区分 `clean_passes` 与 `retry_passes`
- 根因类必须落在四分类之一;分类为"未知"须显式标注并给下一步取证动作

## 速查

| 场景 | 动作 | 禁止 |
|------|------|------|
| 首跑失败原样重跑通过 | 判 first-run-flaky,进工作流一定性 | 当作稳定通过放行 |
| 重跑绿了,开发说"修好了" | 要求给出根因与修复 diff;无则维持隔离 | 重试绿当修复证据 |
| 夜间全量靠 retries=3 撑绿 | 驳回;给隔离+排期方案与诚实门禁语义 | 调大 retries/超时变绿 |
| 隔离清单越攒越长 | 升级:≥3 轮未修条目上抛排期 | 静默跳过或删除用例 |
| 发布前套件"全绿" | 核三项:首次通过率/重试救回/隔离数 | 只看最终绿就放行 |

## 反模式

| 反模式 | 后果 | 替代 |
|--------|------|------|
| 重跑变绿就放过(不标 D 不追踪) | flaky 混入绿灯名单,覆盖虚减,真回归随机漏网 | D 类跨轮追踪,≥3 轮升级修根因(`../core/triage.md` 第 5 节) |
| 调大 retries/超时"治"flaky | 噪声计成信号,套件变慢且更不可信 | 复跑矩阵定位根因类,按 playbook 修复模式处置 |
| 静默删除 flaky 用例 | 无声减覆盖,且删除的是最会报警的哨兵 | 隔离(fixme/quarantine)+ 排期修复 + 报告可见 |
| 健康度只报"通过率 100%" | 掩盖重试救回与隔离,门禁证据失真 | 三项分开统计(clean/retry/quarantine),机读摘要齐备 |
| flaky 判定凭印象不走复跑矩阵 | 误杀真缺陷或放生噪声 | 判定必须挂矩阵证据;不足则显式"未知"+下一步取证 |

## 在体系中的位置

- `../core/triage.md`:分流层 D 类条目是本 skill 的主要输入;本 skill 是其"套件级治理"的下游
- `../core/pipeline-integration.md`:CI 回流闭环与 headless 语义;本 skill 的隔离/健康度是其 D 类处置的展开
- `../core/report-template.md`:健康度机读摘要的挂靠规范
- `../core/test-type-matrix.md`:轴 7 防 flaky 条款的治理侧展开
- `qa-memory`:flaky 判定的跨会话沉淀(文字协作,非依赖);沉淀条目自带投毒防线要求