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
.agents/qa-project-context.md
first — if it exists, use it and skip anything already answered there. Then:
  1. REST, GraphQL, or both? REST-only suites use standard HTTP assertions. GraphQL needs query/mutation builders and benefits from an introspection-diff snapshot.
  2. Auth mechanism? JWT, API key, OAuth 2.0, or session cookies — each needs a different fixture strategy.
  3. OpenAPI/Swagger spec available? If yes, auto-generate Zod schemas as contracts (
    orval
    ,
    openapi-zod-client
    ) and consider spec-driven fuzzing with Schemathesis.

首先查看
.agents/qa-project-context.md
——如果文件存在,使用其中的内容并跳过已解答的问题。然后询问:
  1. 仅REST、仅GraphQL,还是两者都有? 仅REST的测试套件使用标准HTTP断言。GraphQL需要查询/变更构建器,且从自省差异快照中获益。
  2. 认证机制是什么? JWT、API密钥、OAuth 2.0还是会话Cookie——每种机制需要不同的夹具策略。
  3. 是否有OpenAPI/Swagger规范? 如果有,自动生成Zod Schema作为契约(使用
    orval
    openapi-zod-client
    ),并考虑用Schemathesis进行基于规范的模糊测试。

Core Principles

核心原则

  1. Test contracts, not implementations. Assert on response shape, status codes, and headers — not on internal logic or database state.
  2. Schema validation catches drift before it breaks consumers. A failing schema test means you caught a breaking change before your frontend did.
  3. Auth flows are tests too — don't just hardcode tokens. Test login, refresh, expiration, and permission boundaries.
  4. Response time is a testable assertion. Performance regressions caught in CI are cheaper than production incidents.

  1. 测试契约,而非实现细节。 断言响应结构、状态码和Header——而非内部逻辑或数据库状态。
  2. Schema验证在破坏消费者之前捕获差异。 Schema测试失败意味着你在前端之前就发现了破坏性变更。
  3. 认证流程也是测试的一部分——不要硬编码令牌。 测试登录、刷新、过期以及权限边界。
  4. 响应时间是可测试的断言。 在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:
ToolBest forWhy
Bruno (v3.4+)File-based collections, git-reviewable workflows, FOSS Postman replacementFilesystem-first, no cloud sync required; gRPC + OAuth + GraphQL query builder
Hurl (8.x)Plain-text HTTP testing, CI smoke checksOne file = many requests + assertions; runs anywhere curl runs; certificate + JSONPath (RFC 9535) queries
HoppscotchWeb-based Postman-style explorationOpen source, runs in browser, good for quick checks
Playwright
APIRequestContext
Automated tests in your test runnerThis skill's focus — covered below
Supertest (Node) / httpx (Python)In-process API tests against your own appFastest 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
APIRequestContext
测试运行器中的自动化测试本技能的核心重点——下文详述
Supertest (Node) / httpx (Python)针对自有应用的进程内API测试当你同时控制两端时,反馈速度最快
新项目除非团队已有投入,否则跳过Postman/Insomnia——基于文件的工具(Bruno、Hurl)更易于在PR中评审,且不会出现集合漂移问题。

Playwright API Testing

Playwright API测试

APIRequestContext
supports standalone API tests without launching a browser and shares cookie/storage state with browser contexts. Use it for:
  • Standalone API tests
    request.get/post/...
    with status, header, and body assertions.
  • 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
    APIRequestContext
    to tests, and dispose it on teardown. Never hardcode tokens.
See
references/playwright-setup.md
for the
playwright.config.ts
, standalone tests, combined browser+API test, and the authenticated API fixture.

APIRequestContext
支持无需启动浏览器的独立API测试,并与浏览器上下文共享Cookie/存储状态。可用于:
  • 独立API测试 —— 使用
    request.get/post/...
    进行状态码、Header和响应体断言。
  • 浏览器+API组合测试 —— 通过API预置数据,断言数据在UI中显示,再通过API清理数据。
  • 认证夹具 —— 在夹具中登录一次,将预认证的
    APIRequestContext
    传递给测试,并在销毁时清理。绝不硬编码令牌。
查看
references/playwright-setup.md
获取
playwright.config.ts
、独立测试、浏览器+API组合测试以及认证API夹具的示例。

Schema Validation

Schema验证

Validate response shape against a schema rather than spot-checking individual fields with
toHaveProperty
. Two common approaches:
  • Zod 4 — define a schema,
    safeParse
    the response, and assert
    result.success
    . Log
    result.error.issues
    on failure for a precise diff. Use the Zod 4 native string formats:
    z.email()
    ,
    z.uuid()
    ,
    z.iso.datetime()
    — the chained
    z.string().email()
    forms are deprecated and slated for removal.
  • 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 (
orval
or
openapi-zod-client
). 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.
See
references/schema-validation.md
for the Zod 4, AJV, schema-as-contract, and Schemathesis implementations.

针对Schema验证响应结构,而非用
toHaveProperty
抽查单个字段。两种常见方案:
  • Zod 4 —— 定义Schema,使用
    safeParse
    解析响应,断言
    result.success
    。失败时记录
    result.error.issues
    以获取精确差异。使用Zod 4原生字符串格式:
    z.email()
    z.uuid()
    z.iso.datetime()
    ——链式调用的
    z.string().email()
    形式已被废弃,即将移除。
  • AJV + JSON Schema —— 当已有JSON Schema(例如来自OpenAPI规范)时,使用
    ajv
    +
    ajv-formats
    编译并验证。
Schema即契约: 让API和测试都导入同一个Schema文件。如果响应结构变更,消费者测试会立即失败。如果有OpenAPI规范,自动生成Schema(使用
orval
openapi-zod-client
)。对于规范优先的团队,添加Schemathesis作为CI任务,针对规范对真实API进行模糊测试,捕获未记录的结构和边缘500错误。
查看
references/schema-validation.md
获取Zod 4、AJV、Schema即契约以及Schemathesis的实现示例。

Test Patterns

测试模式

Cover each endpoint with a happy-path test plus at least one error-path test. The common patterns:
  • CRUD lifecycle — a
    describe.serial
    block that creates, reads, updates, deletes, then verifies the 404. Carries the resource id across steps.
  • 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 +
    retry-after
    ). Don't ship happy-path-only suites.
  • Response headers — assert
    content-type
    ,
    cache-control
    , and rate-limit headers directly (not behind a conditional that may never fire). See the pattern below.
  • Pagination — first-page metadata, out-of-bounds empty page, and rejection of invalid page size.
  • File upload/download — multipart upload and
    content-disposition
    header verification.
  • GraphQL — a small
    gql
    helper, then query / mutation / invalid-query (errors array) cases, plus an introspection-diff snapshot to catch silently-removed fields.
  • Webhooks — spin up a throwaway HTTP server, register a webhook, trigger the event, and assert delivery.
See
references/test-patterns.md
for the full runnable implementations of every pattern above plus performance assertions.
为每个端点编写至少一个正常流程测试和一个错误流程测试。常见模式:
  • CRUD生命周期 —— 使用
    describe.serial
    块完成创建、读取、更新、删除操作,然后验证404错误。在步骤间传递资源ID。
  • 认证流程 —— 登录成功、无效凭证(401)、令牌过期(401)、令牌刷新以及权限边界(403)。将认证作为独立的describe块。
  • 错误响应 —— 400(格式错误的请求体)、422(带字段详情的验证错误)、429(速率限制 +
    retry-after
    )。不要只编写正常流程的测试套件。
  • 响应Header —— 直接断言
    content-type
    cache-control
    以及速率限制Header(不要放在可能永远不会触发的条件判断中)。查看下方示例。
  • 分页 —— 第一页元数据、越界空页、无效页大小拒绝。
  • 文件上传/下载 —— 多部分上传和
    content-disposition
    Header验证。
  • GraphQL —— 一个小型
    gql
    工具,然后测试查询/变更/无效查询(错误数组)场景,加上自省差异快照以捕获悄悄移除的字段。
  • Webhook —— 启动临时HTTP服务器,注册Webhook,触发事件,断言交付成功。
查看
references/test-patterns.md
获取上述所有模式的可运行实现以及性能断言示例。

Response Headers

响应Header

Headers carry the contract: cache directives, rate-limit info, content type, CORS policy. Assert them with
response.headers()
and index by lowercase name; don't gate the assertion behind an
if (rateLimited)
that may not fire.
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
retry-after
variants, see
references/test-patterns.md
(Response Header Validation).

Header承载契约:缓存指令、速率限制信息、内容类型、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" | ...
});
速率限制和
retry-after
的变体示例,请查看
references/test-patterns.md
(响应Header验证部分)。

Performance 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
references/test-patterns.md
(Performance Assertions section) for the code.

响应时间和 payload 大小是可测试的断言——断言热点端点在预算内响应(例如500ms)、payload不超过大小上限、API能承受并发请求 burst 而不返回5xx错误。查看
references/test-patterns.md
(性能断言部分)获取代码示例。

Anti-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
if (rateLimited)
may never run and proves nothing.
Header承载缓存指令、速率限制信息、内容类型和CORS策略。直接在所有相关响应上断言——埋在
if (rateLimited)
中的检查可能永远不会执行,无法验证任何内容。

5. No cleanup after test data creation

5. 创建测试数据后不清理

Tests that create resources without deleting them pollute the database. Use
afterEach
/
afterAll
hooks or fixture teardown.
创建资源但不删除的测试会污染数据库。使用
afterEach
/
afterAll
钩子或夹具清理逻辑。

6. 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
    toHaveProperty
    spot-checks.
  • Header assertions exist for at least
    content-type
    and any cache/rate-limit headers the API sets, asserted unconditionally.
  • 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
    抽查。
  • 至少对
    content-type
    以及API设置的缓存/速率限制Header进行无条件断言。
  • 为被其他团队或服务消费的端点设置契约测试(共享Schema文件;如需消费者驱动验证,请使用
    contract-testing
    )。
  • 真实第三方调用(支付网关、外部SaaS)已被模拟或虚拟化;API及其数据库真实运行。
  • 测试套件的CI任务在测试环境中运行后返回0(绿色)。

Reference Files (in
references/
)

参考文件(位于
references/
目录)

  • playwright-setup.md
    playwright.config.ts
    , standalone API tests, combined browser+API tests, and the authenticated
    APIRequestContext
    fixture.
  • 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 ——
    playwright.config.ts
    、独立API测试、浏览器+API组合测试以及认证
    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层、单元层还是端到端层测试哪些内容。