API Testing Patterns
API testing verifies contracts and behavior from the consumer perspective —
correct responses, proper error handling, acceptable performance. Focus on what
matters to consumers, not implementation details.
When to use
- Testing REST or GraphQL APIs
- Validating microservice contracts
- Designing API test strategies
- Preventing breaking API changes
- Triggers on "test API", "contract testing", "integration test", "API 测试", "接口测试", "契约测试"
Not for: generating test scaffolds for non-API code (use test-generation); browser/E2E flows (use e2e-testing); the TDD loop itself (use tdd).
Steps
1. Identify the testing level
| Level |
Purpose |
Dependencies |
Speed |
| Contract |
Provider-consumer agreement |
None |
Fast |
| Component |
API in isolation |
Mocked external deps |
Fast |
| Integration |
Real dependencies |
Database, services |
Slower |
2. Test the contract, not implementation
Test from the consumer perspective using schema validation, not exact values.
Consumers depend on the contract (status codes, response shape); they don't
care about internal structure.
Pattern — Consumer-Driven Contracts: schema validation against the contract (status codes, response shape), not exact values — code example in references/templates/api-test-scaffold.md. Use Pact or Spring Cloud Contract for consumer-driven contract testing in microservice architectures.
3. Cover critical scenarios
| Scenario |
Must test |
Example |
| Auth |
401/403 handling |
Expired token, wrong user, cross-user access |
| Input |
400 validation |
Missing fields, wrong types, out-of-range values |
| Errors |
500 graceful handling |
DB down, timeout, upstream failure |
| Idempotency |
Duplicate prevention |
Same idempotency key → same result |
| Concurrency |
Race conditions |
Parallel checkout on shared inventory |
Idempotency: send the same request twice with an Idempotency-Key header;
both responses must return the same orderId (no duplicate created).
4. REST CRUD pattern
Test the full resource lifecycle — CREATE, READ, UPDATE, DELETE — as a sequence
that proves each operation and its side effects. Code example in
references/templates/api-test-scaffold.md.
5. GraphQL-specific checks
- Query validation: reject invalid queries, enforce typed schemas
- Complexity limits: prevent abusive nested queries (depth/complexity analysis)
- Introspection: test against staging schema (production may disable it)
6. Automate and monitor
Automate all API tests in CI/CD with schema validation. Version API tests
alongside the API to prevent breaking changes. Monitor production APIs for
contract drift between deployed behavior and the spec.
Best practices
Do:
- Test from consumer perspective
- Use schema validation (not exact field values)
- Test error scenarios extensively — not just happy paths
- Version API tests with the API
- Mock external services to keep tests fast and deterministic
Avoid:
- Testing implementation, not contract
- Ignoring HTTP semantics (status codes)
- No negative testing
- Asserting on field order or extra fields
- Slow tests (mock external services)
Gotchas
- Tests generated against the documented API must be validated against the
running service first — docs and reality drift
- Auth tokens expire between runs — use fixtures with refresh logic
- Rate limiting in CI causes intermittent 429s — add retry with exponential
backoff
- Idempotency tests need unique request IDs per run — hardcoded IDs cause false
passes on retry
- GraphQL introspection may be disabled in production — test against staging
Output: API test files (contract + integration) under test/ — code, not a report.
Verify
References
- ${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md — discipline every skill shares
- references/templates/api-test-scaffold.md — REST API test scaffold template (Jest/Supertest)
1---2name: api-testing3description: Use when testing APIs or designing API test strategies — contract testing, REST/GraphQL testing, and integration testing. Triggers on "test API", "contract testing", "integration test", "API 测试", "接口测试", "契约测试".4---56# API Testing Patterns78API testing verifies contracts and behavior from the consumer perspective —9correct responses, proper error handling, acceptable performance. Focus on what10matters to consumers, not implementation details.1112## When to use1314- Testing REST or GraphQL APIs15- Validating microservice contracts16- Designing API test strategies17- Preventing breaking API changes18- Triggers on "test API", "contract testing", "integration test", "API 测试", "接口测试", "契约测试"1920**Not for:** generating test scaffolds for non-API code (use `test-generation`); browser/E2E flows (use `e2e-testing`); the TDD loop itself (use `tdd`).2122## Steps2324### 1. Identify the testing level2526| Level | Purpose | Dependencies | Speed |27|-------|---------|--------------|-------|28| Contract | Provider-consumer agreement | None | Fast |29| Component | API in isolation | Mocked external deps | Fast |30| Integration | Real dependencies | Database, services | Slower |3132### 2. Test the contract, not implementation3334Test from the consumer perspective using schema validation, not exact values.35Consumers depend on the contract (status codes, response shape); they don't36care about internal structure.3738**Pattern — Consumer-Driven Contracts:** schema validation against the contract (status codes, response shape), not exact values — code example in [references/templates/api-test-scaffold.md](references/templates/api-test-scaffold.md). Use **Pact** or **Spring Cloud Contract** for consumer-driven contract testing in microservice architectures.3940### 3. Cover critical scenarios4142| Scenario | Must test | Example |43|----------|----------|---------|44| Auth | 401/403 handling | Expired token, wrong user, cross-user access |45| Input | 400 validation | Missing fields, wrong types, out-of-range values |46| Errors | 500 graceful handling | DB down, timeout, upstream failure |47| Idempotency | Duplicate prevention | Same idempotency key → same result |48| Concurrency | Race conditions | Parallel checkout on shared inventory |4950**Idempotency:** send the same request twice with an `Idempotency-Key` header;51both responses must return the same `orderId` (no duplicate created).5253### 4. REST CRUD pattern5455Test the full resource lifecycle — CREATE, READ, UPDATE, DELETE — as a sequence56that proves each operation and its side effects. Code example in57[references/templates/api-test-scaffold.md](references/templates/api-test-scaffold.md).5859### 5. GraphQL-specific checks6061- Query validation: reject invalid queries, enforce typed schemas62- Complexity limits: prevent abusive nested queries (depth/complexity analysis)63- Introspection: test against staging schema (production may disable it)6465### 6. Automate and monitor6667Automate all API tests in CI/CD with schema validation. Version API tests68alongside the API to prevent breaking changes. Monitor production APIs for69contract drift between deployed behavior and the spec.7071## Best practices7273**Do:**7475- Test from consumer perspective76- Use schema validation (not exact field values)77- Test error scenarios extensively — not just happy paths78- Version API tests with the API79- Mock external services to keep tests fast and deterministic8081**Avoid:**8283- Testing implementation, not contract84- Ignoring HTTP semantics (status codes)85- No negative testing86- Asserting on field order or extra fields87- Slow tests (mock external services)8889## Gotchas9091- Tests generated against the documented API must be validated against the92 running service first — docs and reality drift93- Auth tokens expire between runs — use fixtures with refresh logic94- Rate limiting in CI causes intermittent 429s — add retry with exponential95 backoff96- Idempotency tests need unique request IDs per run — hardcoded IDs cause false97 passes on retry98- GraphQL introspection may be disabled in production — test against staging99100**Output:** API test files (contract + integration) under `test/` — code, not a report.101102## Verify103104- [ ] Contract tests cover every consumer expectation105- [ ] Auth: 401 without token, 403 for wrong user, expired token rejected106- [ ] Input validation: missing fields, wrong types, out-of-range values → 400107- [ ] Error states: 500 graceful, timeout handled108- [ ] Idempotency: duplicate request with same key → same result109- [ ] REST resources tested across full CRUD lifecycle110- [ ] Tests automated in CI with schema validation111112## References113114- [${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md](${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md) — discipline every skill shares115- [references/templates/api-test-scaffold.md](references/templates/api-test-scaffold.md) — REST API test scaffold template (Jest/Supertest)