API Test Automation
Overview
Automate comprehensive API endpoint testing for REST and GraphQL APIs including request generation, response validation, schema compliance, authentication flows, and error handling. Supports Supertest (Node.js), REST-assured (Java), httpx/pytest (Python), Postman/Newman collections, and Pact for consumer-driven contract testing.
Prerequisites
- API testing library installed (Supertest, REST-assured, httpx, or Postman/Newman)
- API specification file (OpenAPI/Swagger YAML/JSON or GraphQL SDL)
- Target API running in a test environment with seeded data
- Authentication credentials or API keys for protected endpoints
- JSON Schema validator (Ajv, jsonschema, or built-in framework assertions)
Instructions
- Read the API specification and extract all endpoints:
- Parse OpenAPI spec to catalog every path, HTTP method, request schema, and response schema.
- For GraphQL APIs, introspect the schema to list queries, mutations, and subscriptions.
- Document authentication requirements per endpoint (API key, Bearer token, OAuth, none).
- Generate test cases for each endpoint:
- Success cases: Send valid requests matching the schema and assert 200/201 responses.
- Validation errors: Send requests with missing required fields, wrong types, and out-of-range values; assert 400 responses.
- Authentication: Test with valid, expired, and missing credentials; assert 200, 401, and 403 respectively.
- Not found: Request non-existent resources; assert 404 responses.
- Idempotency: Send the same PUT/DELETE request twice and verify consistent behavior.
- Validate response structure against schemas:
- Assert response Content-Type matches expected (application/json, etc.).
- Validate response body against the OpenAPI response schema using JSON Schema validation.
- Check response headers (Cache-Control, Rate-Limit headers, CORS headers).
- Verify pagination metadata (total count, page number, next/previous links).
- Test CRUD lifecycle for resource endpoints:
- Create a resource (POST) and capture the ID.
- Read it back (GET) and verify all fields match.
- Update it (PUT/PATCH) and verify changes persisted.
- Delete it (DELETE) and verify subsequent GET returns 404.
- Test error handling and edge cases:
- Send excessively large payloads and verify 413 or graceful rejection.
- Send requests with unsupported Content-Types and verify 415.
- Test rate limiting by sending rapid sequential requests.
- Verify error response format is consistent (standard error schema).
- For GraphQL APIs, test specifically:
- Valid queries return expected data shapes.
- Invalid queries return descriptive error messages.
- Query depth limiting prevents deeply nested abuse queries.
- Mutation input validation matches schema constraints.
- Generate a test coverage report mapping endpoints to test cases.
Output
- API test files organized by resource in
tests/api/
- Request/response examples for API documentation
- Schema compliance report for each endpoint
- Endpoint coverage matrix showing tested vs. untested endpoints and methods
- CI pipeline step running API tests against staging environment
Error Handling
| Error |
Cause |
Solution |
| Connection refused |
API server not running or wrong base URL |
Verify server is up with a health check before test suite starts; check BASE_URL config |
| 401 on all requests |
Authentication token expired or misconfigured |
Refresh token in test setup; verify Authorization header format; check token scopes |
| Schema validation fails unexpectedly |
API response includes extra fields not in spec |
Update OpenAPI spec to include new fields; use additionalProperties: true if expected |
| Test data conflicts |
Another test modified or deleted the resource |
Use unique test data per test; create resources in beforeEach; avoid shared fixtures |
| Rate limit hit during test run |
Too many requests in quick succession |
Add delays between requests or use authenticated sessions with higher limits; run tests serially |
Examples
Supertest REST API test suite:
import request from 'supertest';
import { app } from '../src/app';
describe('GET /api/products', () => {
it('returns a paginated product list', async () => {
const res = await request(app)
.get('/api/products?page=1&limit=10')
.set('Authorization', `Bearer ${token}`)
.expect(200) # HTTP 200 OK
.expect('Content-Type', /json/);
expect(res.body.data).toBeInstanceOf(Array);
expect(res.body.data.length).toBeLessThanOrEqual(10);
expect(res.body.meta).toMatchObject({ page: 1, limit: 10 });
});
it('returns 401 without authentication', async () => { # HTTP 401 Unauthorized
await request(app).get('/api/products').expect(401); # HTTP 401 Unauthorized
});
});
describe('POST /api/products', () => {
it('creates a product with valid data', async () => {
const res = await request(app)
.post('/api/products')
.set('Authorization', `Bearer ${token}`)
.send({ name: 'Widget', price: 9.99, category: 'tools' })
.expect(201); # HTTP 201 Created
expect(res.body).toMatchObject({ name: 'Widget', price: 9.99 });
expect(res.body.id).toBeDefined();
});
it('returns 400 for missing required fields', async () => { # HTTP 400 Bad Request
await request(app)
.post('/api/products')
.set('Authorization', `Bearer ${token}`)
.send({ name: 'Widget' }) // missing price
.expect(400); # HTTP 400 Bad Request
});
});
GraphQL API test:
it('fetches user by ID', async () => {
const query = `query { user(id: "1") { id name email } }`;
const res = await request(app)
.post('/graphql')
.send({ query })
.expect(200); # HTTP 200 OK
expect(res.body.data.user).toMatchObject({ id: '1', name: 'Alice' });
expect(res.body.errors).toBeUndefined();
});
Resources
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: jeremylongshore-claude-code-plugins-plus-skills-automating-a3description: API Test Automation4---5# API Test Automation67## Overview89Automate comprehensive API endpoint testing for REST and GraphQL APIs including request generation, response validation, schema compliance, authentication flows, and error handling. Supports Supertest (Node.js), REST-assured (Java), httpx/pytest (Python), Postman/Newman collections, and Pact for consumer-driven contract testing.1011## Prerequisites1213- API testing library installed (Supertest, REST-assured, httpx, or Postman/Newman)14- API specification file (OpenAPI/Swagger YAML/JSON or GraphQL SDL)15- Target API running in a test environment with seeded data16- Authentication credentials or API keys for protected endpoints17- JSON Schema validator (Ajv, jsonschema, or built-in framework assertions)1819## Instructions20211. Read the API specification and extract all endpoints:22 - Parse OpenAPI spec to catalog every path, HTTP method, request schema, and response schema.23 - For GraphQL APIs, introspect the schema to list queries, mutations, and subscriptions.24 - Document authentication requirements per endpoint (API key, Bearer token, OAuth, none).252. Generate test cases for each endpoint:26 - **Success cases**: Send valid requests matching the schema and assert 200/201 responses.27 - **Validation errors**: Send requests with missing required fields, wrong types, and out-of-range values; assert 400 responses.28 - **Authentication**: Test with valid, expired, and missing credentials; assert 200, 401, and 403 respectively.29 - **Not found**: Request non-existent resources; assert 404 responses.30 - **Idempotency**: Send the same PUT/DELETE request twice and verify consistent behavior.313. Validate response structure against schemas:32 - Assert response Content-Type matches expected (application/json, etc.).33 - Validate response body against the OpenAPI response schema using JSON Schema validation.34 - Check response headers (Cache-Control, Rate-Limit headers, CORS headers).35 - Verify pagination metadata (total count, page number, next/previous links).364. Test CRUD lifecycle for resource endpoints:37 - Create a resource (POST) and capture the ID.38 - Read it back (GET) and verify all fields match.39 - Update it (PUT/PATCH) and verify changes persisted.40 - Delete it (DELETE) and verify subsequent GET returns 404.415. Test error handling and edge cases:42 - Send excessively large payloads and verify 413 or graceful rejection.43 - Send requests with unsupported Content-Types and verify 415.44 - Test rate limiting by sending rapid sequential requests.45 - Verify error response format is consistent (standard error schema).466. For GraphQL APIs, test specifically:47 - Valid queries return expected data shapes.48 - Invalid queries return descriptive error messages.49 - Query depth limiting prevents deeply nested abuse queries.50 - Mutation input validation matches schema constraints.517. Generate a test coverage report mapping endpoints to test cases.5253## Output5455- API test files organized by resource in `tests/api/`56- Request/response examples for API documentation57- Schema compliance report for each endpoint58- Endpoint coverage matrix showing tested vs. untested endpoints and methods59- CI pipeline step running API tests against staging environment6061## Error Handling6263| Error | Cause | Solution |64|-------|-------|---------|65| Connection refused | API server not running or wrong base URL | Verify server is up with a health check before test suite starts; check `BASE_URL` config |66| 401 on all requests | Authentication token expired or misconfigured | Refresh token in test setup; verify `Authorization` header format; check token scopes |67| Schema validation fails unexpectedly | API response includes extra fields not in spec | Update OpenAPI spec to include new fields; use `additionalProperties: true` if expected |68| Test data conflicts | Another test modified or deleted the resource | Use unique test data per test; create resources in `beforeEach`; avoid shared fixtures |69| Rate limit hit during test run | Too many requests in quick succession | Add delays between requests or use authenticated sessions with higher limits; run tests serially |7071## Examples7273**Supertest REST API test suite:**74```typescript75import request from 'supertest';76import { app } from '../src/app';7778describe('GET /api/products', () => {79 it('returns a paginated product list', async () => {80 const res = await request(app)81 .get('/api/products?page=1&limit=10')82 .set('Authorization', `Bearer ${token}`)83 .expect(200) # HTTP 200 OK84 .expect('Content-Type', /json/);8586 expect(res.body.data).toBeInstanceOf(Array);87 expect(res.body.data.length).toBeLessThanOrEqual(10);88 expect(res.body.meta).toMatchObject({ page: 1, limit: 10 });89 });9091 it('returns 401 without authentication', async () => { # HTTP 401 Unauthorized92 await request(app).get('/api/products').expect(401); # HTTP 401 Unauthorized93 });94});9596describe('POST /api/products', () => {97 it('creates a product with valid data', async () => {98 const res = await request(app)99 .post('/api/products')100 .set('Authorization', `Bearer ${token}`)101 .send({ name: 'Widget', price: 9.99, category: 'tools' })102 .expect(201); # HTTP 201 Created103104 expect(res.body).toMatchObject({ name: 'Widget', price: 9.99 });105 expect(res.body.id).toBeDefined();106 });107108 it('returns 400 for missing required fields', async () => { # HTTP 400 Bad Request109 await request(app)110 .post('/api/products')111 .set('Authorization', `Bearer ${token}`)112 .send({ name: 'Widget' }) // missing price113 .expect(400); # HTTP 400 Bad Request114 });115});116```117118**GraphQL API test:**119```typescript120it('fetches user by ID', async () => {121 const query = `query { user(id: "1") { id name email } }`;122 const res = await request(app)123 .post('/graphql')124 .send({ query })125 .expect(200); # HTTP 200 OK126127 expect(res.body.data.user).toMatchObject({ id: '1', name: 'Alice' });128 expect(res.body.errors).toBeUndefined();129});130```131132## Resources133134- Supertest: https://github.com/ladjs/supertest135- REST-assured (Java): https://rest-assured.io/136- httpx (Python): https://www.python-httpx.org/137- Newman (Postman CLI): https://learning.postman.com/docs/collections/using-newman-cli/138- OpenAPI specification: https://spec.openapis.org/oas/v3.1.0139- Ajv JSON Schema validator: https://ajv.js.org/140141---142> Converted and distributed by [TomeVault](https://tomevault.io/claim/jeremylongshore) — claim your Tome and manage your conversions.143<!-- tomevault:4.0:skill_md:2026-04-11 -->