api-integration-test skill 解析¶
api-integration-test 是一套围绕内部 API 集成测试设计的安全执行框架。它的核心设计思想是:集成测试首先要判断测试类型是否正确、当前配置是否足够、运行环境是否安全,以及最终产出的测试能否长期被团队理解、执行和审计。 因此它把作用域判断、Go 版本适配、配置完整性、执行模式、安全门禁、构建标签 隔离和结构化输出串成一条固定流程。
1. 定义¶
api-integration-test 是一个面向 Go 内部 HTTP / gRPC API 的集成测试 skill。它用于创建、维护和运行带门禁的内部 API 集成测试,重点覆盖真实配置下的契约验证、故障定位和安全可控执行。它输出的不只是测试代码,还包括执行模式、降级等级、环境变量清单、运行命令和结构化结果报告。
2. 背景与问题¶
这个 skill 要解决的问题是:很多所谓的集成测试,其实在作用域、安全性、可执行性和可维护性上都不够可靠。
如果没有明确框架,常见问题通常集中在 6 类:
| 问题 | 典型后果 |
|---|---|
| 作用域判断错误 | 把第三方 API 测试、单元测试、内部 API 测试混在一起,方法完全不对 |
| 配置不完整却强行写成“可运行” | 测试里充满猜测的地址、凭证或 ID,看起来能跑,实际上不能 |
集成测试默认进入普通 go test ./... | 没有 构建标签,导致 CI 编译时间上升,甚至在不具备依赖的环境中失败 |
| 生产环境保护不足 | 误配环境变量时,测试直接打到生产服务 |
| 超时、重试和失败路径约束不足 | 测试偶发卡死、无限重试,或者只能证明“成功”,不能证明“失败方式正确” |
| 输出不成体系 | 只留下几段代码,没有说明运行前提、未覆盖项、降级原因和复现命令 |
api-integration-test 的设计逻辑,就是先把“这件事该不该做、能做到什么程度、会不会出事故”判断清楚,再决定写什么样的测试。
3. 与常见替代方案的对比¶
在进入设计细节之前,先看它和几种常见做法的区别:
| 维度 | api-integration-test skill | 直接让模型写“集成测试” | 把集成测试当成普通单元测试处理 |
|---|---|---|---|
| 作用域识别 | 强 | 弱 | 弱 |
| 配置完整性检查 | 强 | 弱 | 弱 |
| 生产安全保护 | 强 | 弱 | 弱 |
| 构建标签 隔离 | 强 | 弱 | 弱 |
| 真实配置下的可执行性 | 强 | 中 | 弱 |
| 输出可审计性 | 强 | 弱 | 弱 |
| 超时 / 重试策略 | 强 | 中 | 弱 |
| 与 CI 集成友好度 | 强 | 中 | 弱 |
它并不是要替代通用测试能力,而是把“真实环境下的 API 集成测试”从一个模糊任务,收束成一套可安全落地的流程。
4. 核心设计逻辑¶
4.1 先做作用域判断 vs 先写测试¶
第一个强制门禁是作用域校验门禁。它要求先判断当前任务到底是不是“内部 API 集成测试”。
这一步非常关键,因为“写测试”这个请求表面上很像,但背后的测试类型差别很大:
- 内部 HTTP / gRPC API 集成测试:适合这个 skill
- 纯单元测试:应该转到
unit-test - 第三方供应商 API 测试:应该转到
thirdparty-api-integration-test - 浏览器端到端流程:根本不是这条路径
如果这一步不先做,后面所有“最佳实践”都可能建立在错误对象上。评估报告里的 Eval 2 就说明了这一点:with-skill 已经能识别 GitHub API 属于第三方场景,但当前 hard-stop 语义还不够强,导致它虽然判断对了,仍继续生成了测试代码。也正因为这个边界案例,范围 Gate 在设计上显得尤其重要。
4.2 把 Go 版本单独做成门禁¶
第二个强制门禁是 Go 版本门禁。它要求先读 go.mod,再决定测试代码应该采用什么写法。
这道门禁要解决的,不是“会不会用新特性”,而是“给出的测试模板能不能在当前项目里成立”。例如:
t.Setenv需要 Go 1.17+- 1.22 之前要特别注意 range 变量闭包捕获
- 1.24 之前不应在同一个子测试里把
t.Parallel()和t.Setenv()直接混用
如果忽略这一步,模型写出来的代码可能语法没问题,但放到项目里并不合适,或者会埋下很细的并发 / 测试隔离问题。
4.3 配置完整性比“先写出来再说”更重要¶
第三个强制门禁是配置完整性门禁。它把配置状态拆成三档:
FullScaffoldBlocked
这层设计特别重要,因为真实集成测试最大的风险之一,就是配置不完整时还硬写成“看起来能跑”。
这个 skill 明确拒绝做这件事:
- 配置齐全:生成完整测试
- 缺少部分配置:生成带
t.Skip(...)和// TODO:的脚手架 - 关键信息都不知道:直接停止,只给变量清单和 setup 指引
这样做的价值在于:
- 避免硬编码猜测的地址、凭证、租户 ID
- 让“现在缺什么”一目了然
- 让生成物与实际可执行程度保持一致
它宁愿诚实地输出一个 scaffold,也不愿意伪装出一个“完整但其实跑不起来”的测试。
4.4 先选 Execution 模式¶
第四个强制门禁是执行模式门禁。它把任务自动分成 Smoke、Standard、Comprehensive 三种模式。
这一步的核心作用,是让测试深度和场景风险对齐:
| 模式 | 适用场景 | 设计目的 |
|---|---|---|
Smoke | 连通性检查、首次验证环境、单个只读端点 | 先回答“通不通” |
Standard | 大多数正常内部 API 集成测试 | 兼顾成功路径、失败路径和主要业务断言 |
Comprehensive | 大范围覆盖、迁移后验证、高风险接口 | 补充并发、大载荷、分页、限流等更完整检查 |
如果没有这层模式划分,最常见的两个失真就是:
- 小检查被写得过重,使用成本过高
- 高风险接口被只用一个“200 OK”级别的 smoke case 带过去
4.5 生产安全必须做成强制门禁¶
第五个强制门禁是生产环境安全门禁。它要求:
ENV=prod/production时默认t.Skip- 只有显式设置
INTEGRATION_ALLOW_PROD=1才允许继续 - 对破坏性操作还要额外要求
INTEGRATION_ALLOW_DESTRUCTIVE=1
这是整个 skill 最有安全价值的一层设计。评估报告也把它列为 with-skill 独有能力:3 个场景里 with-skill 全对,without-skill 全错。
它解决的问题非常直接:很多集成测试一旦门禁变量被误开,就可能直接访问真实环境。如果没有这层保护,所谓“测试”就有可能变成生产事故入口。
而且它不是单点防护,而是两层:
- 运行门禁变量控制“允不允许跑”
- 生产环境门禁控制“即使允许跑,也不能默认打到生产”
这就是为什么评估报告把它称为 safety-critical dimension。
4.6 构建标签 隔离是必需项 vs 细节优化¶
api-integration-test 强制要求集成测试文件带上:
//go:build integration// +build integration
这看起来只是文件头的两行,但实际是整个设计里非常关键的一层。
评估报告显示,without-skill 在 3 个场景里都漏掉了这一步。它的影响包括:
go test ./...会把这些测试编译进去- CI 编译时间增加
- 在没有集成测试依赖的环境里,单是编译阶段就可能失败
所以 构建标签 隔离不是“写得更规范一点”,而是在代码层面明确宣告:这不是默认测试路径的一部分,它必须被显式启用。
4.7 走真实传输路径 vs mock 掉关键部分¶
这个 skill 明确反对“把要集成的客户端 mock 掉”。因为一旦把真实 http.Client 或 gRPC 连接替换成 fake,这件事本质上就退化成了单元测试。
这里的设计重点是:集成测试的价值,在于验证真实传输路径、真实配置解析、真实协议契约,而不是仅仅验证业务函数会返回什么。
因此它要求:
- 使用真实 client 实例,或真实 handler +
httptestserver - 走生产代码路径构建请求
- 同时校验协议级和业务级结果
这让它和“看起来也像集成测试”的伪集成测试区分得非常清楚。
4.8 超时和重试要严格受控¶
这个 skill 对 context.WithTimeout、bounded retry 和 ctx.Done() 检查有很明确的要求。
它想解决的,不是“怎样让测试更顽强”,而是“怎样让测试在不掩盖真实故障的前提下更稳定”。
如果对重试和超时不设边界,常见后果有:
- 无限重试,把真正的失败藏起来
- 测试卡住,不知道是服务挂了还是代码没收尾
- 使用
http.Post/http.Get这类不带 context 的快捷函数,导致取消和超时行为不可控
评估报告里 Eval 3 很清楚地体现了这一点:without-skill 直接用了 http.Post,没有统一的 context timeout;with-skill 则能保持一致的超时控制。
4.9 同时断言协议级和业务级结果¶
api-integration-test 不满足于只断言 HTTP 200 或 require.NoError。它要求同时检查:
- 协议级契约:状态码、gRPC code、必要响应字段
- 业务级不变量:身份映射、状态转换、关键数值约束
这是因为很多 API 集成测试最常见的失真就是“请求发通了,所以测试通过了”。但一个请求“通了”,不代表返回的数据就满足业务语义。
这种设计的价值在于,它把测试目标从“连通性验证”提升为“契约和语义同时验证”。
4.10 结构化输出¶
这个 skill 明确要求在结果汇报时加载共享的 输出契约,并以结构化方式汇报执行结果。评估报告也显示,with-skill 的输出会稳定包含以下信息:
- 执行模式
- 降级级别
- 门禁变量
- 精确命令
- 超时 / 重试策略
- 结果摘要
- 质量评分卡
它解决的是一个非常现实的问题:很多测试代码即使写出来了,团队还是不知道:
- 这些测试依赖哪些环境变量
- 当前是完整实现还是 scaffold
- 到底执行了没有
- 没执行的话,为什么没执行
- 应该用什么命令复现
结构化输出的意义,就是把“测试代码”升级成“测试交付物”。这也是为什么评估报告把 输出契约 视为 skill 独有能力。
4.11 支持降级 vs 非黑即白¶
这个 skill 不是简单分成“能写”或“不能写”,而是允许 Full / Scaffold / Blocked 三种输出层级。
这种设计很成熟,因为真实项目里的信息往往不是一开始就齐全的。如果只有全量成功和完全失败两种结果,模型很容易在中间状态里走向两个坏方向:
- 要么明明信息不够,却硬写出一套伪完整方案
- 要么一缺东西就完全停工,没有任何可继续推进的产物
而降级设计允许输出一个诚实、可继续演进的中间结果。这比“写得很完整但全靠猜”更有工程价值。
4.12 CI 集成被放在后面 vs 前面¶
api-integration-test 不是一上来就讲 GitHub Actions、Makefile target 或 Docker Compose,而是先把作用域、安全、配置和执行约束讲清楚,最后才提 CI 集成。
这体现了一个很好的设计取舍:先保证测试本身定义正确,再考虑怎么把它接进 CI。
否则很容易出现一种倒置:
- CI 流程配好了
- 测试看起来也跑了
- 但测试本身其实没有 构建标签、没有 prod safety、没有明确 gate env
从这个角度看,CI 只是放大器,前面的安全和边界设计才是地基。
5. 这个设计解决了哪些具体问题¶
从 SKILL.md 和评估报告可以看出,这个 skill 重点解决的是以下几类工程问题:
| 问题类型 | skill 中的对应设计 | 实际效果 |
|---|---|---|
| 测试类型判断错误 | 作用域校验门禁 | 能区分内部 API、第三方 API 和单元测试场景 |
| 测试模板与项目 Go 版本不匹配 | Go 版本门禁 | 避免生成不适合当前 Go 版本的测试写法 |
| 配置不足却假装可运行 | Configuration Completeness Gate + 降级等级 | 输出与真实可执行程度一致 |
| 集成测试误入默认测试路径 | 构建标签 隔离 | 避免普通 go test ./... 编译并触发这些测试 |
| 测试误打生产环境 | 生产环境安全门禁 | 默认拒绝生产环境执行,必要时显式二次授权 |
| 超时 / 重试策略失控 | context.WithTimeout + bounded retry 规则 | 提高稳定性,同时避免掩盖真实故障 |
| 只验证“通不通”,不验证“对不对” | 协议级 + 业务级双重断言 | 让测试更接近真实契约验证 |
| 输出不可复用、不可审计 | 输出契约 | 团队能直接知道前提、结果、缺口和复现方式 |
评估报告的数据也支持这一点:with-skill 总体通过率是 94.7%,without-skill 只有 57.9%;在 构建标签 隔离、生产环境安全门禁 和 输出契约 三个维度上,with-skill 是 3/3 全对,而 without-skill 是 0/3。这说明它的价值不只是“代码写得更完整”,而是把集成测试真正变成一种安全、清晰、可长期维护的交付物。
6. 主要亮点¶
6.1 先判断“该不该写”,再判断“怎么写”¶
这是整个 skill 最重要的亮点。它把作用域验证放在最前面,尽量避免一开始就朝错误测试类型投入精力。当前评估也说明,这一层的识别能力已经很强,但 hard-stop 语义还可以继续加强。
6.2 安全门禁做得非常扎实¶
生产环境安全门禁、destructive gate、构建标签 隔离,这几层组合起来,让它在“不会误伤生产环境”这件事上远强于 baseline。
6.3 对“不完整信息”处理得很诚实¶
Full / Scaffold / Blocked 这套降级模型很实用。它既不一缺信息就彻底停工,也不在信息不足时装作一切都齐了。
6.4 测试不是只为了能跑,而是为了能诊断¶
输出契约、Exact Commands、Timeout / Retry Policy、质量评分卡,这些设计都说明它追求的不只是“生成测试文件”,而是“生成之后团队知道怎么跑、为什么跳过、失败时该怎么看”。
6.5 在 baseline 最薄弱的几个维度上形成明显差异¶
从评估报告看,这个 skill 的独特优势几乎都出现在 baseline 很容易漏掉的地方:
- 构建标签
- prod safety
- 作用域判断
- 结构化报告
也就是说,它并不是主要靠“多懂一点 HTTP / gRPC”取胜,而是靠对集成测试交付边界的系统化控制取胜。
7. 什么时候适合用,什么时候不该硬用¶
| 场景 | 是否适合 | 原因 |
|---|---|---|
| 给内部 HTTP / gRPC API 写真实配置下的集成测试 | 适合 | 这是它的核心场景 |
| 排查内部 API 集成测试失败 | 适合 | 结构化输出和模式选择对 triage 很有帮助 |
| 需要在 CI 中引入 gated integration tests | 适合 | 构建标签、环境门禁和输出约束都很适合这种场景 |
| 纯单元测试 | 不适合 | 应该转到 unit-test |
| 第三方供应商 API 测试 | 不适合 | 应该转到 thirdparty-api-integration-test |
| 浏览器端到端流程 | 不适合 | 这不是 API integration test 的范畴 |
8. 结论¶
api-integration-test 的真正亮点,不是它能写出一段请求代码,而是它把内部 API 集成测试里最容易出问题的环节系统化了:先判断作用域,确认 Go 版本和配置状态,再决定执行模式,随后用生产安全、构建标签、超时 / 重试、契约断言和结构化输出来约束最终交付物。
从设计上看,这个 skill 很典型地体现了生产级集成测试的几个原则:先保证测试类型和运行前提正确,再追求覆盖度;先把安全边界立住,再允许执行;先把未覆盖项写清楚,再谈测试是否“完成”。 这也是它为什么特别适合真实内部 API 场景,而不是泛泛地替代所有测试工作。
9. 文档维护¶
当以下内容发生变化时,这份文档应该同步更新:
skills/api-integration-test/SKILL.md的 强制门禁、执行模式、安全规则 或 输出契约 发生变化。skills/api-integration-test/references/*.md中的作用域门禁、输出格式、模式样例或高级模式发生变化。evaluate/api-integration-test-skill-eval-report.zh-CN.md中支撑本文结论的关键数据发生变化。- 项目对内部 API 集成测试、生产环境保护、CI 运行方式或门禁环境变量的团队约束发生变化。
建议按季度复查一次;如果 api-integration-test skill 有明显重构,则应立即复查。
10. 相关阅读¶
skills/api-integration-test/SKILL.mdskills/api-integration-test/references/common-integration-gate.mdskills/api-integration-test/references/common-output-contract.mdskills/api-integration-test/references/checklists.mdskills/api-integration-test/references/internal-api-patterns.mdskills/api-integration-test/references/advanced-patterns.mdevaluate/api-integration-test-skill-eval-report.zh-CN.md