关于 api-testing
面向验证 HTTP 端点和模拟外部服务的 API 测试技能,介绍使用 Supertest 进行集成测试,以及用 MSW 在网络层拦截请求,并涵盖响应断言、结构校验和错误场景。
主要功能
- 01使用 Supertest 测试端点
- 02使用 MSW 模拟 HTTP 与 GraphQL
- 03断言状态码、标头和响应正文
- 04校验响应结构
- 05Cookie 持久化与框架测试客户端
适用场景
- 01测试 REST API 集成
- 02验证请求与响应契约
- 03在测试中模拟第三方服务
- 04检查错误响应和边界情况
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill api-testing安装后在 Claude Code 中输入/api-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/assertion-patterns.mdmsw-handlers.mdsupertest-patterns.mdtest-organization.md详细介绍
API 测试
概述
API 测试通过发送请求并断言响应来验证 HTTP 端点,涵盖状态码、标头、正文内容和错误处理。Supertest 提供流畅、可链式调用的 API,可对 Express、Fastify 和 Hono 应用进行集成测试,无需启动真实服务。MSW(Mock Service Worker)v2 在网络层拦截发出的 HTTP 请求,可在 Node.js 测试和浏览器环境中逼真地模拟外部服务。
适用场景: REST API 集成测试、测试中间件流水线、验证请求/响应契约、在测试中模拟第三方 API、测试错误处理和边界情况。
不适用场景: 纯函数单元测试(直接使用断言)、浏览器端到端测试(使用 Playwright/Cypress)、负载/性能测试(使用 k6/Artillery)、静态文件服务测试。
快速参考
| 模式 | API | 要点 |
|---|---|---|
| GET 请求 | request(app).get('/path') | 返回 supertest Test 对象 |
| 带正文的 POST 请求 | request(app).post('/path').send(body) | 自动设置 Content-Type |
| 身份验证标头 | .set('Authorization', 'Bearer token') | 在 .expect() 之前链式调用 |
| 状态断言 | .expect(200) | 可与正文断言链式调用 |
| 正文断言 | .expect({ key: 'value' }) | 深度相等性检查 |
| 标头断言 | .expect('Content-Type', /json/) | 接受字符串或正则表达式 |
| MSW HTTP 处理程序 | http.get('/api/users', resolver) | 拦截匹配的请求 |
| MSW GraphQL 处理程序 | graphql.query('GetUser', resolver) | 按操作名称拦截 |
| MSW 响应 | HttpResponse.json(data, { status }) | v2 响应格式 |
| MSW 错误模拟 | HttpResponse.error() | 模拟网络故障 |
| MSW 一次性处理程序 | http.get(path, resolver, { once: true }) | 首次匹配后自动移除 |
| MSW 单测覆盖 | server.use(handler) | 在特定测试中覆盖默认处理程序 |
| 架构验证 | schema.parse(response.body) | 使用 Zod 验证响应结构 |
| Cookie 持久化 | const agent = request.agent(app) | 在多个请求间保留 Cookie |
| Fastify 注入 | app.inject({ method, url }) | 内置测试方式,无需 supertest |
| Hono 测试客户端 | testClient(app) | 类型安全的请求构造器 |
常见错误
| 错误 | 正确做法 |
|---|---|
| 未等待 supertest 请求 | 始终使用 await request(app).get('/path') |
| 在测试之间共享服务状态 | 在 afterEach 中使用 server.resetHandlers() 重置处理器 |
| 直接模拟 fetch/axios | 使用 MSW 在网络层拦截 |
在设置中忘记 server.listen() | 在 beforeAll 中调用,并在 afterEach 中调用 resetHandlers |
| 将 Fastify 实例传给 supertest | 使用 fastify.server(底层 Node 服务) |
| 在响应完成前进行断言 | 使用 await 或返回 supertest 链 |
| 在多个测试中硬编码测试数据 | 使用工厂或测试数据固定项 |
| 不测试错误响应 | 除了正常路径,也要测试 4xx 和 5xx 路径 |
在 afterEach 中使用 server.close() | 使用 afterAll 关闭服务,afterEach 仅用于重置 |
| 断言时忽略响应标头 | 验证 Content-Type、Cache-Control 和 CORS 标头 |
未使用 onUnhandledRequest: 'error' | 捕获未处理的请求,避免测试遗漏未被发现 |
| 测试实现而非行为 | 断言响应结构,而非内部函数调用 |
委派
- 测试结构审查:使用
TaskAgent - 代码审查:委派给
code-reviewerAgent - 模式探索:使用
ExploreAgent
如果有
vitest-testing技能,请将通用 Vitest 配置和模式委派给它。 否则,建议使用:npx skills add oakoss/agent-skills --skill vitest-testing
参考资料
评论
支持 Markdown