Claude-skill-registry api-testing-patterns
Comprehensive API testing patterns including contract testing, REST/GraphQL testing, and integration testing. Use when testing APIs or designing API test strategies.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/api-testing-patterns-proffesor-for-testin-agentic-qe" ~/.claude/skills/majiayu000-claude-skill-registry-api-testing-patterns && rm -rf "$T"
manifest:
skills/data/api-testing-patterns-proffesor-for-testin-agentic-qe/SKILL.mdsource content
API Testing Patterns
<default_to_action> When testing APIs or designing API test strategy:
- IDENTIFY testing level: contract, integration, or component
- TEST the contract, not implementation (consumer perspective)
- VALIDATE auth, input, errors, idempotency, concurrency
- AUTOMATE in CI/CD with schema validation
- MONITOR production APIs for contract drift
Quick Pattern Selection:
- Microservices → Consumer-driven contracts (Pact)
- REST APIs → CRUD + pagination + filtering tests
- GraphQL → Query validation + complexity limits
- External deps → Mock with component testing
- Performance → Load test critical endpoints
Critical Success Factors:
- APIs are contracts - test from consumer perspective
- Always test error scenarios, not just happy paths
- Version your API tests to prevent breaking changes </default_to_action>
Quick Reference Card
When to Use
- Testing REST or GraphQL APIs
- Validating microservice contracts
- Designing API test strategies
- Preventing breaking API changes
Testing Levels
| Level | Purpose | Dependencies | Speed |
|---|---|---|---|
| Contract | Provider-consumer agreement | None | Fast |
| Component | API in isolation | Mocked | Fast |
| Integration | Real dependencies | Database, services | Slower |
Critical Test Scenarios
| Scenario | Must Test | Example |
|---|---|---|
| Auth | 401/403 handling | Expired token, wrong user |
| Input | 400 validation | Missing fields, wrong types |
| Errors | 500 graceful handling | DB down, timeout |
| Idempotency | Duplicate prevention | Same idempotency key |
| Concurrency | Race conditions | Parallel checkout |
Tools
- Contract: Pact, Spring Cloud Contract
- REST: Supertest, REST-assured, Playwright
- Load: k6, Artillery, JMeter
Agent Coordination
: Validate contracts, detect breaking changesqe-api-contract-validator
: Generate tests from OpenAPI specqe-test-generator
: Load test endpointsqe-performance-tester
: API security testingqe-security-scanner
Contract Testing
Pattern: Consumer-Driven Contracts
// Consumer defines expectations const contract = { request: { method: 'POST', path: '/orders', body: { productId: 'abc', quantity: 2 } }, response: { status: 201, body: { orderId: 'string', total: 'number' } } }; // Provider must fulfill test('order API meets contract', async () => { const response = await api.post('/orders', { productId: 'abc', quantity: 2 }); expect(response.status).toBe(201); expect(response.body).toMatchSchema({ orderId: expect.any(String), total: expect.any(Number) }); });
When: Microservices, distributed systems, third-party integrations
Critical Test Patterns
Authentication & Authorization
describe('Auth', () => { it('rejects without token', async () => { expect((await api.get('/orders')).status).toBe(401); }); it('rejects expired token', async () => { const expired = generateExpiredToken(); expect((await api.get('/orders', { headers: { Authorization: `Bearer ${expired}` } })).status).toBe(401); }); it('blocks cross-user access', async () => { const userAToken = generateToken({ userId: 'A' }); expect((await api.get('/orders/user-B-order', { headers: { Authorization: `Bearer ${userAToken}` } })).status).toBe(403); }); });
Input Validation
describe('Validation', () => { it('validates required fields', async () => { const response = await api.post('/orders', { quantity: 2 }); // Missing productId expect(response.status).toBe(400); expect(response.body.errors).toContain('productId is required'); }); it('validates types', async () => { expect((await api.post('/orders', { productId: 'abc', quantity: 'two' })).status).toBe(400); }); it('validates ranges', async () => { expect((await api.post('/orders', { productId: 'abc', quantity: -5 })).status).toBe(400); }); });
Idempotency
it('prevents duplicates with idempotency key', async () => { const key = 'unique-123'; const data = { productId: 'abc', quantity: 2 }; const r1 = await api.post('/orders', data, { headers: { 'Idempotency-Key': key } }); const r2 = await api.post('/orders', data, { headers: { 'Idempotency-Key': key } }); expect(r1.body.orderId).toBe(r2.body.orderId); // Same order });
Concurrency
it('handles race condition on inventory', async () => { const promises = Array(10).fill().map(() => api.post('/orders', { productId: 'abc', quantity: 1 }) ); const responses = await Promise.all(promises); const successful = responses.filter(r => r.status === 201); const inventory = await db.inventory.findById('abc'); expect(inventory.quantity).toBe(initialQuantity - successful.length); });
REST CRUD Pattern
describe('Product CRUD', () => { let productId; it('CREATE', async () => { const r = await api.post('/products', { name: 'Widget', price: 10 }); expect(r.status).toBe(201); productId = r.body.id; }); it('READ', async () => { const r = await api.get(`/products/${productId}`); expect(r.body.name).toBe('Widget'); }); it('UPDATE', async () => { const r = await api.put(`/products/${productId}`, { price: 12 }); expect(r.body.price).toBe(12); }); it('DELETE', async () => { expect((await api.delete(`/products/${productId}`)).status).toBe(204); expect((await api.get(`/products/${productId}`)).status).toBe(404); }); });
Best Practices
✅ Do This
- Test from consumer perspective
- Use schema validation (not exact values)
- Test error scenarios extensively
- Version API tests
- Automate in CI/CD
❌ Avoid This
- Testing implementation, not contract
- Ignoring HTTP semantics (status codes)
- No negative testing
- Asserting on field order or extra fields
- Slow tests (mock external services)
Agent-Assisted API Testing
// Validate contracts await Task("Contract Validation", { spec: 'openapi.yaml', endpoint: '/orders', checkBreakingChanges: true }, "qe-api-contract-validator"); // Generate tests from spec await Task("Generate API Tests", { spec: 'openapi.yaml', coverage: 'comprehensive', include: ['happy-paths', 'input-validation', 'auth-scenarios', 'error-handling'] }, "qe-test-generator"); // Load test await Task("API Load Test", { endpoint: '/orders', rps: 1000, duration: '5min' }, "qe-performance-tester"); // Security scan await Task("API Security Scan", { spec: 'openapi.yaml', checks: ['sql-injection', 'xss', 'broken-auth', 'rate-limiting'] }, "qe-security-scanner");
Agent Coordination Hints
Memory Namespace
aqe/api-testing/ ├── contracts/* - API contract definitions ├── generated-tests/* - Generated test suites ├── validation/* - Contract validation results └── performance/* - Load test results
Fleet Coordination
const apiFleet = await FleetManager.coordinate({ strategy: 'contract-testing', agents: ['qe-api-contract-validator', 'qe-test-generator', 'qe-test-executor'], topology: 'mesh' }); await apiFleet.execute({ services: [ { name: 'orders-api', consumers: ['checkout-ui', 'admin-api'] }, { name: 'payment-api', consumers: ['orders-api'] } ] });
Related Skills
- agentic-quality-engineering - API testing with agents
- tdd-london-chicago - London school for API testing
- performance-testing - API load testing
- security-testing - API security validation
- contract-testing - Consumer-driven contracts deep dive
Remember
API testing = verifying contracts and behavior, not implementation. Focus on what matters to consumers: correct responses, proper error handling, acceptable performance.
With Agents: Agents automate contract validation, generate comprehensive test suites from specs, and monitor production APIs for drift. Use agents to maintain API quality at scale.