| name | fullstack-slice-testing |
| description | 局部前后端接缝测试执行器(stack-agnostic / project-agnostic)。当一个 feature 的前后端两侧都收尾、 需要把"单前端阶段拿来 mock 的那份假设"与"单后端的真实行为"做一次对账时使用:在**单 feature 内**, 让消费者侧(前端/调用方)↔ 提供者侧(后端/被调方)的**单条切片**以真实形态对接、停止 mock,验证接缝。 它是 backend-testing / frontend-testing 的对账——单前端 mock 撒的谎(字段/类型/状态码/错误体/鉴权/时序) 在这里穿帮。**仅限单 feature 内单切片,不跨 feature**(跨多 feature 旅程属"完整功能链路"第四格)。覆盖四个 能力缺口——环境编排(让两侧+依赖以真实形态可复现一键起来)、契约真实性(消费者 mock↔提供者规格比对)、 接缝粘合(凭证透传/序列化往返/错误映射/头部跨域)、真实时序(条件命中:仅切片含流式/实时/异步才测)。 与前两格的根本区别——新难点是"起真栈(环境编排)"而非写断言:前两格能把另一侧 mock 掉,这格不能, 必须真把两侧拉活。先读两侧栈清单按栈实例化编排/契约工具,再 RED→GREEN 补接缝断言并固化为回归。 触发词:局部前后端测试 / 前后端接缝测试 / 切片对账 / 真前后端对接 / 起真栈集成 / 契约漂移验证 / 消费者契约对账 / fullstack slice testing / seam testing / contract drift / 前后端集成补测。 遵循 testing-system-blueprint 蓝本(风险分级 / 可追溯 / 发布门 / 三层节奏),受自愈护栏约束(只写测试不改 产品码、断言不可弱化、禁伪造修复、有界重试、产 PR 人审)。被 test-routing-advisor 判定"局部前后端"时调用, 也可直接触发。兄弟:backend-testing(单后端)/ frontend-testing(单前端)。 |
fullstack-slice-testing · 局部前后端接缝测试执行器
这个 skill 解决什么
backend-testing 把前端 mock 掉、单独验后端的真实;frontend-testing 把后端 mock 掉、单独验前端的渲染与交互契约。
两者都对各自一侧做到了真实,但都建立在对另一侧的假设之上——前端单测里那份手写或从契约生成的 mock,
就是"前端以为后端会这么返回"的一纸假设。这纸假设从未与真实后端碰过面。
局部前后端测试就是这次碰面。 它在单个 feature 内,把消费者侧(前端 / 调用方)和提供者侧
(后端 / 被调方)的一条切片,以真实形态对接、停止 mock,验证接缝是否真的对得上。
本质上它是一次对账:单前端阶段为了独立开发而对后端撒的"善意的谎"(字段名、类型、状态码、错误体、
鉴权头、时序),在这里集中穿帮。
核心边界(务必读懂):本格仅限单 feature 内的单条切片,不跨 feature。
"用户从 A feature 走到 B feature 再到 C feature"这种跨多 feature 的端到端旅程,属于第四格
"完整功能链路",不是这里。这里只问一件事:这一个 feature 里,前端那条对后端的假设,和后端真实行为对得上吗?
圈切片时不要贪多——一个 feature 可能有多条消费者→提供者接缝,先圈出风险最高的那条,逐条来。
关键洞:本格的新难点不在写断言,而在"起真栈"。 前两格之所以能各自独立跑,是因为它们把另一侧
mock 掉了——mock 是个"廉价的假人",随起随用。这一格的全部价值恰恰是不许 mock 那一侧,
于是你必须真把两侧 + 它们依赖的中间件同时、可复现地拉活起来。这件"环境编排"的事,是前两格从未
面对过的难点,等价于前端的"装运行器"、后端的"起测试库"——栈起不来,后面所有断言都无从谈起。
遵循 testing-system-blueprint 蓝本(按名引用即可):风险分级排序、可追溯 ID、发布门、三层节奏。
两条绝对约束(先读,贯穿全程)
- stack-agnostic(栈无关):四个能力缺口一律用"能力描述 + 按栈实例化 lookup"表达,绝不把某一栈
写死为唯一答案。本文与
references/gaps.md 里出现的 docker-compose / testcontainers / Playwright /
Cypress / gstack /qa / MSW / Pact / OpenAPI 等,都只是"某栈/某生态的实例示例",绝不是唯一解。
先读两侧的栈清单(package.json / pyproject.toml / go.mod 等),再实例化对应工具。
尤其 gstack 不是硬依赖——它只是"diff-aware E2E 工具"在某环境下的一个实例;环境里没有它,就回退到
通用 E2E(Playwright / Cypress 等)。本 skill 不写任何 gstack 安装步骤。
- project-agnostic(项目无关):不出现任何业务名词,也不绑定任何具体框架或协议。所有项目专有的东西
——编排文件长什么样、接缝走不走流式(是不是 SSE / WebSocket / 长轮询)、具体接口形状、token / 鉴权机制、
跨域策略、健康检查地址——一律运行时现读、绝不写进 skill,也绝不预设。一律写成条件式:
"若切片含流式/实时交互,则……"、"若两侧用 OpenAPI 声明契约,则……"。
特别强调:流式不是固定缺口,它是"真实时序能力"的条件命中项——非流式切片根本不命中它,不要硬测。
四个能力缺口(都是能力,不是工具)
| # | 能力缺口 | 它验证什么 | 实例示例(lookup,非唯一解) |
|---|
| 1 | 环境编排能力(本格核心难点) | 让切片两侧 + 依赖以真实形态、同时、可复现起来,本地与 CI 一致,健康检查通过 | 容器编排 / 测试容器 / 进程编排 / 内存测试服务器 |
| 2 | 契约真实性能力 | 验证消费者侧假设(单前端阶段拿来 mock 的那份)与提供者侧真实行为是否一致:字段 / 类型 / 状态码 / 错误体 | 消费者 mock↔提供者规格比对 / 双向契约 / schema 比对 |
| 3 | 接缝粘合能力 | 身份/凭证透传、序列化往返、错误→消费者侧处理映射、头部 / 跨域 | 真接口集成断言 |
| 4 | 真实时序/实时能力(条件命中) | 仅切片含流式/实时/异步交互才命中:验时序与增量行为(边收边处理 / race / 最终一致) | 流式协议观察 |
缺口 1 是本格独有的难点,缺口 4 是条件命中(非流式切片直接跳过)。缺口 2/3 是接缝对账的主体。
工作流(六步闭环)
骨架与前两格同构,差异集中在步骤①"起真栈"——这是本格最大的、独有的工程难点。
步骤 0 · 识栈 + 圈切片
- 识两侧栈:分别读消费者侧与提供者侧的栈清单(
package.json / pyproject.toml / go.mod / pom.xml…),
后续编排与契约工具都据此实例化。两侧可能异栈(前端 JS/TS + 后端 Python),编排要兼容两者。
- 圈切片:从契约声明 / AC / 依赖图里,圈出"本 feature 的 消费者→提供者 接缝是哪一条"。
一个 feature 可能有多条接缝,只圈风险最高的单条先做(单切片,不贪多),其余逐条来。
圈的同时确认这条切片真有没有跨进别的 feature——若跨了,它属第四格"完整功能链路",不在本格。
找不到栈清单或圈不出明确接缝就停下来问,别假设。
步骤 1 · 起真栈(本格核心难点,不可跳过)
这是本 skill 与前两格最大的流程差异。 等价于前端的"装运行器"、后端的"起测试库"——
栈起不来,后面全免谈。 这一步只做一件事:验证 / 建立"切片两侧 + 它们依赖的中间件,能一键、
可复现地以真实形态起来,且健康检查通过",并保证本地与 CI 行为一致。
- 读项目里现成的编排定义(运行时现读,不预设它长什么样):可能是容器编排文件、进程启动脚本、
Makefile target、CI 里的 service 定义……有就复用,让"一条命令把两侧 + 依赖拉活"先成立。
- 若没有可复用的编排:按两侧栈实例化一套最小编排(见
references/gaps.md 缺口 1),把
提供者侧、消费者侧、以及它们依赖的中间件(数据库 / 缓存 / 队列等,具体有哪些运行时现读)一起拉起,
配健康检查(等到两侧 ready 才算起好,不靠固定 sleep)。
- 冒烟验证地基可用:起栈后先打通一条最简单的真实请求(消费者真的发、提供者真的收、真的回),
证明栈活了,再进入分层断言。这一步绿之前,不写任何接缝断言。
⚠️ 顺序铁律:现成的 E2E 工具(无论 gstack /qa 还是 Playwright / Cypress)通常不负责起栈——
它们只探测一个已经在跑的 localhost 地址。所以步骤 1 起栈必须在步骤 3 跑 E2E 之前完成,
否则 E2E 探到的是空地址,全红且红得没意义。
步骤 2 · 条件命中(只测这条切片真有的能力)
不是四个缺口全测,只对这条切片实际命中的子集补。逐项判断(详见 references/gaps.md):
| 缺口 | 命中条件 | 不命中示例 |
|---|
| ① 环境编排 | 永远命中(本格前提:必须真把两侧拉活,否则不成其为接缝测试) | —(不命中就不是本格) |
| ② 契约真实性 | 切片有契约漂移风险——前端那份 mock 与后端真实响应可能对不上 | 接口形状极简且双方共用同一份生成代码、几乎无漂移空间 |
| ③ 接缝粘合 | 切片有鉴权 / 凭证透传 / 复杂序列化 / 明确的错误路径 / 跨域 | 无鉴权、纯简单 JSON 往返、无错误分支 |
| ④ 真实时序/实时 | 切片真的含流式 / 实时 / 异步交互(运行时确认协议,别假设) | 非流式切片——普通请求-响应,直接跳过,不要硬造时序测试 |
缺口 4 是典型的"条件命中":先运行时确认这条切片到底是不是流式/实时,是才测时序,不是就跳过。
非流式切片只命中 ①②③ 是完全正常的,不要为了凑满四格硬写时序断言。
步骤 3 · 两层落地
对每个命中的缺口,按"先黑盒冒烟、再结构化断言"两层落地:
- 第一层 · 黑盒冒烟:在已起好的真栈上,跑端到端冒烟,确认这条切片"整条通"。
- 若环境里存在 diff-aware E2E 工具(如 gstack
/qa 为其一),优先用它(能聚焦改动相关的切片,省时)。
- 否则回退通用 E2E(Playwright / Cypress 或该栈等价物)。
- 再次强调:这些工具只探测已跑的 localhost,不起栈——所以步骤 1 必须已把栈拉活。
- 第二层 · 结构化接缝断言:按命中能力(②③④)写可重复跑的接缝断言——这才是把"对账"固化成回归的部分。
黑盒冒烟只证"通了",结构化断言才证"字段/类型/状态码/错误体/凭证/时序逐项对得上"。
具体工具与断言模式见 references/gaps.md,按步骤 0 识别的两侧栈取对应行。
步骤 4 · RED→GREEN + 数据隔离
按"最便宜的命中缺口优先"补:
- 数据隔离先行:接缝测试跑在真栈上,必须有 seed / teardown fixture 保证每次测试数据可控、
互不污染、可重复(起一份已知数据 → 测 → 清掉)。没有隔离,接缝测试会因脏数据假红/假绿。
- RED:先写会失败的接缝断言,确认它因真实接缝缺陷而红(前端假设与后端真实对不上、凭证没透传、
错误体没映射、时序乱了),而不是因为测试写错或栈没起好而红。真红有理,才往下走。
- GREEN:让断言转绿。
- 若红暴露的是真实接缝 bug(典型:前端 mock 撒的谎在这里穿帮了)——HALT,不要自己改产品码
(见自愈护栏),回交
superpowers:test-driven-development / superpowers:systematic-debugging 修,
修完再回本 skill 把回归固化。
- 若只是缺覆盖、接缝本就对得上——补测后即绿,无需改产品码。
- 断言不可弱化:禁止为了转绿而放松断言(如把状态码断言改成
or 200、把错误体校验删掉、把时序断言注释掉)。
步骤 5 · 按蓝本归档 + 拆栈 + PR 人审
每条新增的接缝回归测试:
- 按
testing-system-blueprint 的风险分级排序进发布门——越权 / 契约漂移属高风险(前者放行别人数据、
后者上真后端必崩),进发布门硬阻断;轻微的提示/兜底差异可告警级。
- 挂可追溯 ID(关联 feature / AC / 圈定的切片 / 命中的缺口)。
- 对齐三层节奏:接缝测试要起真栈,天然属较慢层(蓝本 L2 集成层),不要塞进 L1 单测层快跑。
- 拆栈(teardown):CI 里的节奏是 起栈 → 测 → 拆栈,测完务必把真栈和数据一并清理,
避免环境泄漏污染下一次。本地同理(起栈和拆栈成对出现)。
- 补测以 PR 形式交付,由人审核合并;PR 说明列出:圈定的切片、命中缺口、跳过缺口及理由
(尤其注明"切片非流式,缺口④不命中"这类)、每条新增回归对应的缺口与风险级别、起栈/拆栈方式。
四个能力缺口落地结构速览(详见 references/gaps.md)
逐项 = 一个能力缺口。所有工具列均为某栈/某生态的示例实例,按栈实例化,不锁定。
| # | 能力缺口 | 示例实例(lookup,非唯一解) | 命中性 | 闭环性 |
|---|
| ① | 环境编排(本格难点) | 容器编排(docker-compose 等)/ 测试容器(testcontainers 等)/ 进程编排 / 内存测试服务器 | 永远命中 | 全自动(起栈→冒烟→拆栈) |
| ② | 契约真实性 | 消费者 mock↔提供者规格比对 / 双向契约(如 Pact)/ OpenAPI schema 比对 | 有漂移风险才命中 | 全自动 RED→GREEN |
| ③ | 接缝粘合 | 真接口集成断言(真凭证透传 / 真序列化往返 / 错误映射 / 头部跨域) | 有鉴权/错误路径才命中 | 全自动 RED→GREEN |
| ④ | 真实时序/实时(条件命中) | 流式协议观察(运行时确认是 SSE / WebSocket / 长轮询 / 异步回调中的哪种再实例化) | 仅切片真含流式/实时才命中 | 全自动,时序断言较脆需稳化 |
关键区别于前两格(务必讲清)
前两格(backend-testing / frontend-testing)的共同前提是:可以把另一侧 mock 掉,于是各自能独立、廉价地跑。
本格的全部价值恰恰相反——不许 mock 那一侧,必须真把两侧拉活做对账。由此带来两个本质区别:
- 新难点是"起真栈(环境编排)",不是写断言。 前两格的难点在断言(后端自建越权/并发断言、前端翻译视觉契约);
本格的断言反而是接缝层面的常规集成断言,真正难的是步骤①——让异栈两侧 + 中间件一键、可复现、本地=CI 地起来。
这是前两格从未面对的工程难点,所以本 skill 把它单列为不可跳过的核心步骤。
- 本格是前两格的"对账"。 单前端为了独立开发,对后端撒了一份 mock 的"谎"(前端以为后端会这么返回);
单后端则各管各的真实。这两侧的真实/假设从未对过账。 本格就是那次对账——
单前端 mock 撒的谎,在这里穿帮。 这也解释了为什么缺口②"契约真实性"是主体:它专门抓"假设 vs 真实"的差。
自愈护栏(不可越过)
补测过程允许有界自动迭代(起栈 → RED → GREEN → 拆栈),但受以下护栏约束(沿用 blueprint 的护栏):
- 只写测试 / 编排配置,不改产品码——这是默认动作。本 skill 负责起栈、配编排、写接缝断言,不修业务实现。
- 断言不可弱化——禁止为转绿放松断言(如把状态码断言放宽成
or 200、删错误体校验、注释掉时序断言、
把契约比对的字段集缩小)。转绿必须靠正确产品码或正确测试,不靠降标准。
- 禁伪造修复——不得用
skip、固定 sleep 假装等到 ready、把不许 mock 的那一侧偷偷 mock 回去、
起一个假后端冒充真栈等手段伪装通过。本格一旦 mock 掉被测的那一侧,就退化成了前两格,失去全部意义。
- 有界重试升级——起栈/时序天然有 flake(端口竞争、健康检查抖动、流式增量乱序);自动迭代有上限,
连续失败达上限即停止并升级给人,绝不靠"再跑一次就好"掩盖真实的接缝不稳定。
- 产 PR 人审——所有产物(编排配置 + 接缝回归测试)以 PR 交付,人工审核后合并。
- 发现真 bug 要 HALT,回交 superpowers 修——本 skill 不自行改产品代码。补测中若 RED 暴露的是
真实接缝缺陷(前端假设与后端真实对不上、凭证没透传、错误没映射、时序错乱等),停下来,
把缺陷回交
superpowers:test-driven-development / superpowers:systematic-debugging 走修复闭环,
修完再回本 skill 把回归固化。
护栏的目的:让接缝对账可以自动跑,但任何"把被测一侧 mock 回去""栈没真起就假装通过""越界改产品码"的捷径都被堵死。
与上下游的关系
- 上游:
test-routing-advisor 判定"局部前后端"时调用本 skill(也可被用户直接触发)。
- 蓝本:所有归档/分级/发布门/节奏遵循
testing-system-blueprint(按名引用,不在此复制其内容)。
- 兄弟:
backend-testing(单后端)/ frontend-testing(单前端)——本格是这两格的对账:
它们各自把另一侧 mock 掉独立验真,本格把两侧拉活验接缝,让单前端 mock 撒的谎穿帮。
- 边界:跨多 feature 的端到端旅程属第四格"完整功能链路",不是本格;本格只管单 feature 内单切片。
- 方法论复用:发现真接缝缺陷的修复与调试复用
superpowers:test-driven-development 和
superpowers:systematic-debugging(本 skill HALT 后回交它们)。