| name | testing-system-blueprint |
| description | 测试体系蓝本(testing blueprint / test strategy)——一份 stack-agnostic、project-agnostic 的"测试作为体系"方法骨架。当需要确定测试策略、做风险分级(P0–P3)、建立需求↔测试可追溯、 规划三层测试节奏、设计闭环补测、定义发布 go/no-go 门(release gate)时遵循本蓝本。 触发词:测试体系蓝本、测试策略、测试策略蓝本、风险分级、可追溯、需求追溯、发布门、 闭环补测、testing blueprint、test strategy、test pyramid、release gate。 它被 test-routing-advisor(路由器)和各类别测试 skill(如 backend-testing)共同遵循。 本蓝本只给"方法与标准",不写死任何语言/框架/工具,不执行测试也不强制门禁—— 能力是通用原语,工具由调用方读项目栈后实例化;门禁的强制由 CI/hook/pre-commit 承担。 |
测试体系蓝本(Testing System Blueprint)
这是什么 / 不是什么
是:把"测试"从"写一堆用例"升级成"一套体系"的方法骨架。它定义六个能力维度与一套节奏,
让任何语言、任何框架、任何项目都能套用同一套思考方式来决定"测什么、何时测、测到什么程度、何时放行"。
不是:测试执行器,也不是某一技术栈的测试指南。本蓝本不告诉你"用 pytest 还是 jest",
只告诉你"在这一层你需要的是单元 + 契约能力,工具由你读项目栈后实例化"。
谁用它:test-routing-advisor(决定一个任务该走哪类测试)与各类别测试 skill
(如 backend-testing、frontend-testing)。它们把本蓝本的抽象原语,落到具体栈与具体项目上。
两条绝对约束(贯穿全文)
- stack-agnostic(与栈无关):本蓝本只规定"能力 / 维度 / 方法",绝不锁定某一栈的工具或库。
凡举例工具,一律以"按栈实例化"的多栈示例形式给出(Python / Node / Go / JVM …),
并明确:具体工具由调用方读项目栈后实例化,本蓝本不替你选。
- project-agnostic(与项目无关):不出现任何业务名词。通用测试概念
(BOLA、真库、迁移、并发、契约、幂等)允许使用,因为它们是跨项目的通用原语。
六个能力维度(速览,细节见 references)
| # | 维度 | 一句话 | 细节 |
|---|
| 1 | 风险分级 P0–P3 | 按风险决定"必测/该测/可延后",而非堆覆盖率 | references/risk-tiers.md |
| 2 | 需求↔测试可追溯 | 每条验收标准一个稳定 ID,测试引用它,双向校验 | references/traceability.md |
| 3 | 三层测试节奏 | L1 每 task → L2 feature 全绿 → L3 全部完 | 下方 §三层节奏 |
| 4 | 闭环补测法 | 检测缺口 → 生成 → 跑 → 修 → 固化为回归 | references/closed-loop-backfill.md |
| 5 | 发布 go/no-go 门 | 合并前的机械门禁;标准在此,强制靠 CI | references/release-gate.md |
| 6 | 能力→工具映射原则 | 能力是通用原语,工具按栈实例 | references/capability-tool-mapping.md |
附加护栏:自愈式补测的 5 条安全护栏见 references/self-heal-guardrails.md(作为参考,
在让任何"自动生成/自动修复测试"的流程动手前务必先读)。
一、风险分级测试设计 P0–P3(核心理念)
完整判据见 references/risk-tiers.md。这里给骨架。
测试预算永远有限。蓝本主张:不追逐覆盖率数字,而是按"出事的代价 × 出事的概率"给每条行为定级,
让有限的测试工时优先压在最贵的失败上。
- P0 必测:失败即不可逆损害——数据损坏/丢失、权限越界(任何用户拿到不属于自己的数据/操作)、
资金或额度错算、安全边界击穿。这一档不允许"延后",是发布门的硬性输入。
- P1 该测:失败造成核心流程不可用,但可恢复——主用例走不通、关键集成断裂、对外契约破坏。
- P2 可延后:边缘路径、非关键降级、提示文案、非核心配置。
- P3 可不测:纯展示、无逻辑透传、临时脚手架。
定级是行为的属性,不是模块的属性:同一个模块里,"扣减额度"是 P0,"返回提示文案"可能是 P2。
权限相关行为(典型如 BOLA / 越权读写)默认进 P0,除非有明确理由降级。
二、需求↔测试可追溯(双向不漏)
完整规则与校验脚本思路见 references/traceability.md。这里给骨架。
体系的可信度来自"需求和测试能对上"。做法:
- 每条验收标准(AC)给一个稳定 ID(如
AC-007.3),ID 一旦发布不重排、不复用。
- 每个测试在元数据/命名/注释里引用它覆盖的 AC ID(如测试名含
AC-007.3 或注解 @covers AC-007.3)。
- 双向机械校验:
- 无孤儿需求:不存在"有 AC 但没有任何测试引用"的情况(= 漏测)。
- 无幽灵需求:不存在"测试引用了一个不存在的 AC ID"的情况(= 需求已删/打错号,测试在裸奔)。
可追溯不是文档负担,而是**让发布门能机械地回答"这条需求测了没"**的前提——没有 ID,门就只能靠人肉判断。
三、三层测试节奏(WHEN:什么时候测什么)
蓝本把"何时测"和"测什么"解耦。同一类测试在不同时机价值不同,盲目"全都跑"既慢又掩盖问题。
L1 · 每个 task(开发期,TDD 红绿)
- 测什么:单元测试 + 契约测试(对外接口的形状/语义约定)。
- 怎么做:先写失败测试(红)→ 实现到最小通过(绿)→ 必要时重构。这是 TDD 主循环。
- 为什么在这层:缺陷在产生它的那一刻被抓住最便宜;契约在 task 内锁定,后续集成才有依据。
L2 · feature 全绿后(集成冒烟 + review)
- 测什么:feature 内部模块间的集成冒烟——真实依赖(真库、真迁移、真队列)跑通主路径。
- 关键纪律:集成测试绑 feature 边界,不绑项目边界。一个 feature 的所有 task 绿了,
就在这个 feature 的边界内做集成验证;不要等整个项目做完才第一次把模块拼起来。
- 为什么:feature 是"一组协同 task 的最小可验证单元",在它的边界上做集成,
问题域小、定位快;拖到项目级才集成,等于把所有集成风险堆到最后。
L3 · 全部完成后(全链路 E2E + 跨模块一致性)
- 测什么:跨 feature 的端到端用户旅程 + 跨模块数据/状态一致性。
- 关键心态:L3 是"补网",不是"首次发现 bug"的地方。如果一个本该在 L1/L2 抓住的缺陷
到 L3 才暴露,那是 L1/L2 漏了,应回填到对应层级,而不是把 L3 当成兜底垃圾桶。
- 为什么:E2E 慢且脆,只适合验证"整条链路确实通"这一件 L1/L2 无法覆盖的事;
把单元级断言塞进 E2E 会让套件又慢又难维护。
三层不是先后审批关卡,而是缺陷应在哪一层被最便宜地抓住的指南。越靠左越便宜。
四、闭环补测法(缺口 → 固化为回归)
完整流程与判定见 references/closed-loop-backfill.md。这里给骨架。
体系化测试不止"补一次测",而是一个闭环循环,确保每个被发现的缺口都变成长期防回归的资产:
检测缺口 → 生成测试(复现缺口,先红)→ 跑 → 修产品码到绿 → 固化为回归测试(进常驻套件)
补测前先对每个候选缺口分类,避免做无用功:
- ✅ 已被开发期 TDD/契约覆盖 → 跳过。这条行为在 L1 已有红绿历史,重复补测是浪费。
- 🔧 结构性缺口 → 待闭环补。从未被任何层测到的真实风险(典型:跨模块边界、
错误路径、并发/幂等、权限越界),这才是闭环补测要吃的目标。
"固化为回归"是闭环的收尾,也是它和"临时跑一次测试"的本质区别:补出来的测试必须并入常驻套件,
否则同一个 bug 会再回来。
五、发布 go/no-go 门(机械门禁)
完整门项清单见 references/release-gate.md。这里给骨架与边界。
合并/发布前必须满足的机械判据(任一不满足 = no-go):
- 测试全绿:相关层级(至少 P0/P1 对应测试)全部通过,无 skip 掩盖、无 flaky 放行。
- 无孤儿需求:可追溯校验通过——每条 AC 都有测试引用(见 §二)。
- 无破坏性契约变更:对外契约若变更,必须是兼容变更,或已显式声明并被消费方确认。
关于"机械"二字的边界(必须明确):本蓝本只给放行标准,不替你强制执行。
门的真正强制必须落到 CI 流水线 / git hook / pre-commit 等自动化设施上——
由它们在合并前自动跑这些判据并卡住不达标的变更。本 skill 是"标准的来源",不是"门本身"。
把强制写进自动化,才能让门不依赖人的自觉。
六、stack-agnostic 工具映射原则
完整多栈对照表见 references/capability-tool-mapping.md。这里给原则。
蓝本里出现的一切都是能力(capability)——通用原语,如"单元断言""HTTP 契约""真库集成""E2E 驱动"。
工具(tool)是能力在某个栈里的实例,由调用方读完项目实际技术栈后选定。
原则:先确定需要哪个能力,再把能力实例化为该栈的工具;蓝本永远停在能力层,不锁工具。
示意(仅说明"同一能力在不同栈有不同实例",不构成推荐、不锁定):
| 能力(通用原语) | Python 示例 | Node 示例 | Go 示例 | JVM 示例 |
|---|
| 单元/断言 | 该栈主流单测框架 | 该栈主流单测框架 | 内置 testing | 该栈主流单测框架 |
| HTTP/接口契约 | 契约/schema 校验库 | 契约/schema 校验库 | 契约/schema 校验库 | 契约/schema 校验库 |
| 真库集成 | 临时真实数据库实例 | 临时真实数据库实例 | 临时真实数据库实例 | 临时真实数据库实例 |
| E2E 驱动 | 浏览器/API 驱动器 | 浏览器/API 驱动器 | 浏览器/API 驱动器 | 浏览器/API 驱动器 |
表里故意不写死库名——具体到哪个库,由 test-routing-advisor 或类别 skill 读项目栈后实例化。
怎么用本蓝本(给遵循它的 skill)
- 路由器(test-routing-advisor):用 §一 给任务定级、用 §三 决定落到哪一层、用 §六 把能力交给对应栈的类别 skill。
- 类别 skill(如 backend-testing):在自己负责的栈里,把 §六 的能力实例化为具体工具,
按 §二 维护可追溯,按 §四 做闭环补测,最终对齐 §五 的发布门。
- 任何"自动生成/自动修复测试"的动作,先读
references/self-heal-guardrails.md 的 5 条护栏。