api-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<objective>
A response that adds a nullable field or quietly drops one slips past `toHaveProperty` spot-checks and silently breaks the frontend in production. Schema-as-contract tests catch that drift in CI, not prod. This skill produces REST and GraphQL API tests that assert response shape, status codes, headers, auth boundaries, and timing — against a real test environment, not a mocked stand-in.
</objective>
<objective>
如果API响应新增了可空字段或悄悄移除了某个字段,`toHaveProperty`的抽查无法发现问题,会在生产环境中无声地破坏前端。而Schema即契约测试可以在CI阶段就捕获这种差异,避免带到生产环境。本技能可生成REST和GraphQL API测试,针对真实测试环境(而非模拟环境)断言响应结构、状态码、Header、认证边界以及响应时间。
</objective>
Discovery Questions
探索问题
Check first — if it exists, use it and skip anything already answered there. Then:
.agents/qa-project-context.md- REST, GraphQL, or both? REST-only suites use standard HTTP assertions. GraphQL needs query/mutation builders and benefits from an introspection-diff snapshot.
- Auth mechanism? JWT, API key, OAuth 2.0, or session cookies — each needs a different fixture strategy.
- OpenAPI/Swagger spec available? If yes, auto-generate Zod schemas as contracts (,
orval) and consider spec-driven fuzzing with Schemathesis.openapi-zod-client
首先查看——如果文件存在,使用其中的内容并跳过已解答的问题。然后询问:
.agents/qa-project-context.md- 仅REST、仅GraphQL,还是两者都有? 仅REST的测试套件使用标准HTTP断言。GraphQL需要查询/变更构建器,且从自省差异快照中获益。
- 认证机制是什么? JWT、API密钥、OAuth 2.0还是会话Cookie——每种机制需要不同的夹具策略。
- 是否有OpenAPI/Swagger规范? 如果有,自动生成Zod Schema作为契约(使用、
orval),并考虑用Schemathesis进行基于规范的模糊测试。openapi-zod-client
Core Principles
核心原则
- Test contracts, not implementations. Assert on response shape, status codes, and headers — not on internal logic or database state.
- Schema validation catches drift before it breaks consumers. A failing schema test means you caught a breaking change before your frontend did.
- Auth flows are tests too — don't just hardcode tokens. Test login, refresh, expiration, and permission boundaries.
- Response time is a testable assertion. Performance regressions caught in CI are cheaper than production incidents.
- 测试契约,而非实现细节。 断言响应结构、状态码和Header——而非内部逻辑或数据库状态。
- Schema验证在破坏消费者之前捕获差异。 Schema测试失败意味着你在前端之前就发现了破坏性变更。
- 认证流程也是测试的一部分——不要硬编码令牌。 测试登录、刷新、过期以及权限边界。
- 响应时间是可测试的断言。 在CI阶段捕获性能回归比处理生产事件成本更低。
Exploratory vs Automated: Tooling
探索性测试vs自动化测试:工具选择
API exploration (debugging, manual probing, OpenAPI playground) and automated API testing are different jobs. Use the right tool for each:
| Tool | Best for | Why |
|---|---|---|
| Bruno (v3.4+) | File-based collections, git-reviewable workflows, FOSS Postman replacement | Filesystem-first, no cloud sync required; gRPC + OAuth + GraphQL query builder |
| Hurl (8.x) | Plain-text HTTP testing, CI smoke checks | One file = many requests + assertions; runs anywhere curl runs; certificate + JSONPath (RFC 9535) queries |
| Hoppscotch | Web-based Postman-style exploration | Open source, runs in browser, good for quick checks |
Playwright | Automated tests in your test runner | This skill's focus — covered below |
| Supertest (Node) / httpx (Python) | In-process API tests against your own app | Fastest feedback when you control both sides |
Skip Postman/Insomnia for new projects unless your team already has investment there — file-based tools (Bruno, Hurl) are easier to review in PRs and survive when collections drift.
API探索(调试、手动探测、OpenAPI playground)和自动化API测试是不同的工作,要为每项工作选择合适的工具:
| 工具 | 最佳适用场景 | 原因 |
|---|---|---|
| Bruno (v3.4+) | 基于文件的集合、可通过Git评审的工作流、开源Postman替代工具 | 优先基于文件系统,无需云同步;支持gRPC + OAuth + GraphQL查询构建器 |
| Hurl (8.x) | 纯文本HTTP测试、CI冒烟检查 | 单个文件包含多个请求+断言;可在任何能运行curl的环境中执行;支持证书 + JSONPath (RFC 9535) 查询 |
| Hoppscotch | 基于Web的Postman风格探索 | 开源,在浏览器中运行,适合快速检查 |
Playwright | 测试运行器中的自动化测试 | 本技能的核心重点——下文详述 |
| Supertest (Node) / httpx (Python) | 针对自有应用的进程内API测试 | 当你同时控制两端时,反馈速度最快 |
新项目除非团队已有投入,否则跳过Postman/Insomnia——基于文件的工具(Bruno、Hurl)更易于在PR中评审,且不会出现集合漂移问题。
Playwright API Testing
Playwright API测试
APIRequestContext- Standalone API tests — with status, header, and body assertions.
request.get/post/... - Combined browser + API tests — seed data via API, assert it appears in the UI, then clean up via API.
- Authenticated fixtures — log in once in a fixture, hand a pre-authenticated to tests, and dispose it on teardown. Never hardcode tokens.
APIRequestContext
See for the , standalone tests, combined browser+API test, and the authenticated API fixture.
references/playwright-setup.mdplaywright.config.tsAPIRequestContext- 独立API测试 —— 使用进行状态码、Header和响应体断言。
request.get/post/... - 浏览器+API组合测试 —— 通过API预置数据,断言数据在UI中显示,再通过API清理数据。
- 认证夹具 —— 在夹具中登录一次,将预认证的传递给测试,并在销毁时清理。绝不硬编码令牌。
APIRequestContext
查看获取、独立测试、浏览器+API组合测试以及认证API夹具的示例。
references/playwright-setup.mdplaywright.config.tsSchema Validation
Schema验证
Validate response shape against a schema rather than spot-checking individual fields with . Two common approaches:
toHaveProperty- Zod 4 — define a schema, the response, and assert
safeParse. Logresult.successon failure for a precise diff. Use the Zod 4 native string formats:result.error.issues,z.email(),z.uuid()— the chainedz.iso.datetime()forms are deprecated and slated for removal.z.string().email() - AJV with JSON Schema — when you already have JSON Schema (e.g. from an OpenAPI spec), compile and validate with +
ajv.ajv-formats
Schema-as-contract: have both the API and the tests import the same schema file. If the response shape changes, consumer tests fail immediately. With an OpenAPI spec, auto-generate the schema ( or ). For spec-first teams, add Schemathesis as a CI job to fuzz the live API against the spec and catch undocumented shapes and edge-case 500s.
orvalopenapi-zod-clientSee for the Zod 4, AJV, schema-as-contract, and Schemathesis implementations.
references/schema-validation.md针对Schema验证响应结构,而非用抽查单个字段。两种常见方案:
toHaveProperty- Zod 4 —— 定义Schema,使用解析响应,断言
safeParse。失败时记录result.success以获取精确差异。使用Zod 4原生字符串格式:result.error.issues、z.email()、z.uuid()——链式调用的z.iso.datetime()形式已被废弃,即将移除。z.string().email() - AJV + JSON Schema —— 当已有JSON Schema(例如来自OpenAPI规范)时,使用+
ajv编译并验证。ajv-formats
Schema即契约: 让API和测试都导入同一个Schema文件。如果响应结构变更,消费者测试会立即失败。如果有OpenAPI规范,自动生成Schema(使用或)。对于规范优先的团队,添加Schemathesis作为CI任务,针对规范对真实API进行模糊测试,捕获未记录的结构和边缘500错误。
orvalopenapi-zod-client查看获取Zod 4、AJV、Schema即契约以及Schemathesis的实现示例。
references/schema-validation.mdTest Patterns
测试模式
Cover each endpoint with a happy-path test plus at least one error-path test. The common patterns:
- CRUD lifecycle — a block that creates, reads, updates, deletes, then verifies the 404. Carries the resource id across steps.
describe.serial - Auth flows — login success, invalid credentials (401), expired token (401), token refresh, and permission boundary (403). Treat auth as its own describe block.
- Error responses — 400 (malformed body), 422 (validation with field details), 429 (rate limit + ). Don't ship happy-path-only suites.
retry-after - Response headers — assert ,
content-type, and rate-limit headers directly (not behind a conditional that may never fire). See the pattern below.cache-control - Pagination — first-page metadata, out-of-bounds empty page, and rejection of invalid page size.
- File upload/download — multipart upload and header verification.
content-disposition - GraphQL — a small helper, then query / mutation / invalid-query (errors array) cases, plus an introspection-diff snapshot to catch silently-removed fields.
gql - Webhooks — spin up a throwaway HTTP server, register a webhook, trigger the event, and assert delivery.
See for the full runnable implementations of every pattern above plus performance assertions.
references/test-patterns.md为每个端点编写至少一个正常流程测试和一个错误流程测试。常见模式:
- CRUD生命周期 —— 使用块完成创建、读取、更新、删除操作,然后验证404错误。在步骤间传递资源ID。
describe.serial - 认证流程 —— 登录成功、无效凭证(401)、令牌过期(401)、令牌刷新以及权限边界(403)。将认证作为独立的describe块。
- 错误响应 —— 400(格式错误的请求体)、422(带字段详情的验证错误)、429(速率限制 + )。不要只编写正常流程的测试套件。
retry-after - 响应Header —— 直接断言、
content-type以及速率限制Header(不要放在可能永远不会触发的条件判断中)。查看下方示例。cache-control - 分页 —— 第一页元数据、越界空页、无效页大小拒绝。
- 文件上传/下载 —— 多部分上传和Header验证。
content-disposition - GraphQL —— 一个小型工具,然后测试查询/变更/无效查询(错误数组)场景,加上自省差异快照以捕获悄悄移除的字段。
gql - Webhook —— 启动临时HTTP服务器,注册Webhook,触发事件,断言交付成功。
查看获取上述所有模式的可运行实现以及性能断言示例。
references/test-patterns.mdResponse Headers
响应Header
Headers carry the contract: cache directives, rate-limit info, content type, CORS policy. Assert them with and index by lowercase name; don't gate the assertion behind an that may not fire.
response.headers()if (rateLimited)typescript
test('GET /api/users sets expected response headers', async ({ request }) => {
const response = await request.get('/api/users');
const headers = response.headers();
expect(headers).toBeDefined();
expect(headers['content-type']).toContain('application/json');
expect(headers['cache-control']).toBeDefined(); // "no-store" | "max-age=60" | ...
});For the rate-limit and variants, see (Response Header Validation).
retry-afterreferences/test-patterns.mdHeader承载契约:缓存指令、速率限制信息、内容类型、CORS策略。使用并通过小写名称索引来断言;不要将断言放在这类可能永远不会执行的条件中。
response.headers()if (rateLimited)typescript
test('GET /api/users sets expected response headers', async ({ request }) => {
const response = await request.get('/api/users');
const headers = response.headers();
expect(headers).toBeDefined();
expect(headers['content-type']).toContain('application/json');
expect(headers['cache-control']).toBeDefined(); // "no-store" | "max-age=60" | ...
});速率限制和的变体示例,请查看(响应Header验证部分)。
retry-afterreferences/test-patterns.mdPerformance Assertions
性能断言
Response time and payload size are testable assertions — assert that a hot endpoint responds within a budget (e.g. 500ms), that payloads stay under a size ceiling, and that the API survives a burst of concurrent requests without 5xx. See (Performance Assertions section) for the code.
references/test-patterns.md响应时间和 payload 大小是可测试的断言——断言热点端点在预算内响应(例如500ms)、payload不超过大小上限、API能承受并发请求 burst 而不返回5xx错误。查看(性能断言部分)获取代码示例。
references/test-patterns.mdAnti-Patterns
反模式
1. Hardcoded auth tokens
1. 硬编码认证令牌
Tokens expire, rotate, and differ across environments. Use a login fixture that acquires tokens dynamically.
令牌会过期、轮换,且在不同环境中不同。使用登录夹具动态获取令牌。
2. Testing against production
2. 针对生产环境测试
API tests create, modify, and delete data. Run against a dedicated test environment or local instance.
API测试会创建、修改和删除数据。请在专用测试环境或本地实例上运行。
3. Not validating error responses
3. 不验证错误响应
Happy-path-only suites miss the most common production issues. Test 400, 401, 403, 404, and 500 responses for every endpoint.
仅正常流程的测试套件会遗漏最常见的生产问题。为每个端点测试400、401、403、404和500响应。
4. Asserting headers only conditionally
4. 仅在条件下断言Header
Headers carry cache directives, rate limit info, content type, and CORS policy. Assert them directly on every relevant response — a check buried inside may never run and proves nothing.
if (rateLimited)Header承载缓存指令、速率限制信息、内容类型和CORS策略。直接在所有相关响应上断言——埋在中的检查可能永远不会执行,无法验证任何内容。
if (rateLimited)5. No cleanup after test data creation
5. 创建测试数据后不清理
Tests that create resources without deleting them pollute the database. Use / hooks or fixture teardown.
afterEachafterAll创建资源但不删除的测试会污染数据库。使用/钩子或夹具清理逻辑。
afterEachafterAll6. Treating API tests as unit tests
6. 将API测试视为单元测试
Don't mock the database — API tests verify the contract from the consumer's perspective. Mock only genuine third parties you don't own (payment gateways, external SaaS).
不要模拟数据库——API测试从消费者视角验证契约。仅模拟你不拥有的第三方服务(支付网关、外部SaaS)。
7. Ignoring idempotency
7. 忽略幂等性
PUT and DELETE should be idempotent. Test that calling them twice produces the same result.
PUT和DELETE请求应该是幂等的。测试调用两次是否产生相同结果。
Done When
完成标准
- Every target endpoint has at least a happy-path test and at least one error-path test (4xx or 5xx response validated).
- Auth flow tested as its own describe block: successful login, invalid credentials, expired token, and permission boundary (403).
- Schema validation assertions on response shape using Zod 4 or AJV — not just spot-checks.
toHaveProperty - Header assertions exist for at least and any cache/rate-limit headers the API sets, asserted unconditionally.
content-type - Contract tests in place for any endpoint consumed by a different team or service (shared schema file; for consumer-driven verification use ).
contract-testing - Genuine third-party calls (payment gateways, external SaaS) are mocked or virtualized; the API and its database run for real.
- CI job for the suite exits 0 (green) against the test environment.
- 每个目标端点至少有一个正常流程测试和一个错误流程测试(验证4xx或5xx响应)。
- 认证流程作为独立describe块测试:登录成功、无效凭证、令牌过期以及权限边界(403)。
- 使用Zod 4或AJV对响应结构进行Schema验证断言——而非仅使用抽查。
toHaveProperty - 至少对以及API设置的缓存/速率限制Header进行无条件断言。
content-type - 为被其他团队或服务消费的端点设置契约测试(共享Schema文件;如需消费者驱动验证,请使用)。
contract-testing - 真实第三方调用(支付网关、外部SaaS)已被模拟或虚拟化;API及其数据库真实运行。
- 测试套件的CI任务在测试环境中运行后返回0(绿色)。
Reference Files (in references/
)
references/参考文件(位于references/
目录)
references/- playwright-setup.md — , standalone API tests, combined browser+API tests, and the authenticated
playwright.config.tsfixture.APIRequestContext - schema-validation.md — Zod 4 and AJV/JSON-Schema response validation, the schema-as-contract pattern, and Schemathesis spec-driven fuzzing.
- test-patterns.md — Runnable CRUD lifecycle, auth flows, error responses, response headers, pagination, file upload/download, GraphQL (+ introspection diff), webhook, and performance tests.
- playwright-setup.md —— 、独立API测试、浏览器+API组合测试以及认证
playwright.config.ts夹具。APIRequestContext - schema-validation.md —— Zod 4和AJV/JSON-Schema响应验证、Schema即契约模式以及Schemathesis基于规范的模糊测试。
- test-patterns.md —— 可运行的CRUD生命周期、认证流程、错误响应、响应Header、分页、文件上传/下载、GraphQL(+自省差异)、Webhook以及性能测试示例。
Related Skills
相关技能
- contract-testing — Consumer-driven contract verification with Pact/broker; go there when a separate team consumes your API and you need guaranteed compatibility, not just a shared schema.
- playwright-automation — Browser-based E2E testing, Page Object Model, and combined browser + API patterns.
- ci-cd-integration — Running API test suites in CI pipelines, parallelization, and environment management.
- test-strategy — Deciding what to test at the API layer vs. unit vs. E2E.
- contract-testing —— 使用Pact/broker进行消费者驱动的契约验证;当你的API被其他团队消费且需要保证兼容性(而非仅共享Schema)时使用。
- playwright-automation —— 基于浏览器的端到端测试、页面对象模型以及浏览器+API组合模式。
- ci-cd-integration —— 在CI流水线中运行API测试套件、并行化以及环境管理。
- test-strategy —— 决定在API层、单元层还是端到端层测试哪些内容。