API Test Suite Builder
Scan API routes and generate complete test suites automatically.
Install for
Real Conversations
See how the API Test Suite Builder skill responds to actual requests. These are representative examples of what your AI agent will produce.
I have an Express.js API with 23 routes. I've been testing manually with Postman. Can you scan the routes and generate a proper Jest + supertest suite?
With an OpenAPI 3.0 spec and 34 endpoints, the approach is to parse the spec systematically and generate tests in three layers: happy paths, error cases, and edge cases. Here's exactly how this works.
Generation Strategy
For each endpoint in your spec, I extract:
- HTTP method and path
- Required vs optional parameters
- Request body schema (required fields, types, constraints like
minLength,maxLength,enum) - Response schemas for each status code
- Security requirements (JWT Bearer, API keys)
nullableandexamplevalues from the spec
From these, I generate test cases covering every meaningful scenario.
Example Output — POST /api/v1/users
// tests/api/users/create.test.ts
import request from 'supertest';
import { app } from '../../../src/app';
import { getAuthToken, clearUsers } from '../../helpers';
describe('POST /api/v1/users', () => {
let adminToken: string;
beforeAll(async () => {
adminToken = await getAuthToken({ role: 'admin' });
});
afterEach(async () => {
await clearUsers();
});
// ── Happy path ──────────────────────────────────────────
it('201 — creates user with valid payload', async () => {
const res = await request(app)
.post('/api/v1/users')
.set('Authorization', `Bearer ${adminToken}`)
.send({ email: '[email protected]', name: 'Test User', role: 'viewer' });
expect(res.status).toBe(201);
expect(res.body).toMatchObject({
id: expect.any(String),
email: '[email protected]',
name: 'Test User',
role: 'viewer',
});
expect(res.body).not.toHaveProperty('passwordHash'); // PII leak check
expect(res.headers['content-type']).toMatch(/json/);
});
// ── Auth errors ──────────────────────────────────────────
it('401 — rejects request without auth token', async () => {
const res = await request(app)
.post('/api/v1/users')
.send({ email: '[email protected]', name: 'Test User' });
expect(res.status).toBe(401);
});
it('403 — rejects non-admin creating admin user', async () => {
const viewerToken = await getAuthToken({ role: 'viewer' });
const res = await request(app)
.post('/api/v1/users')
.set('Authorization', `Bearer ${viewerToken}`)
.send({ email: '[email protected]', name: 'Test', role: 'admin' });
expect(res.status).toBe(403);
});
// ── Validation errors ────────────────────────────────────
it('422 — rejects missing required fields', async () => {
const res = await request(app)
.post('/api/v1/users')
.set('Authorization', `Bearer ${adminToken}`)
.send({ name: 'Test User' }); // missing email
expect(res.status).toBe(422);
expect(res.body.errors).toEqual(
expect.arrayContaining([
expect.objectContaining({ field: 'email' })
])
);
});
it('422 — rejects invalid email format', async () => {
const res = await request(app)
.post('/api/v1/users')
.set('Authorization', `Bearer ${adminToken}`)
.send({ email: 'not-an-email', name: 'Test User' });
expect(res.status).toBe(422);
});
it('409 — rejects duplicate email', async () => {
const payload = { email: '[email protected]', name: 'User' };
await request(app).post('/api/v1/users').set('Authorization', `Bearer ${adminToken}`).send(payload);
const res = await request(app).post('/api/v1/users').set('Authorization', `Bearer ${adminToken}`).send(payload);
expect(res.status).toBe(409);
});
// ── Edge cases ───────────────────────────────────────────
it('422 — rejects name exceeding maxLength (255 chars)', async () => {
const res = await request(app)
.post('/api/v1/users')
.set('Authorization', `Bearer ${adminToken}`)
.send({ email: '[email protected]', name: 'a'.repeat(256) });
expect(res.status).toBe(422);
});
it('handles special characters in name field', async () => {
const res = await request(app)
.post('/api/v1/users')
.set('Authorization', `Bearer ${adminToken}`)
.send({ email: '[email protected]', name: "O'Reilly <script>alert(1)</script>" });
expect(res.status).toBe(201);
expect(res.body.name).not.toContain('<script>'); // XSS sanitization check
});
});
Handling Authentication Across 34 Endpoints
Most endpoints will share auth setup. A shared helper pattern keeps tests DRY:
// tests/helpers/auth.ts
import jwt from 'jsonwebtoken';
export async function getAuthToken(opts: { role: string; userId?: string }): Promise<string> {
return jwt.sign(
{ sub: opts.userId ?? 'test-user-id', role: opts.role },
process.env.JWT_SECRET!,
{ expiresIn: '1h' }
);
}
For API key auth (if your spec uses apiKey security scheme):
// tests/helpers/auth.ts (API key variant)
export const TEST_API_KEY = 'test-key-do-not-use-in-production';
// Seed this key in your test database setup
Coverage Summary for a 34-Endpoint Spec
| Endpoint category | Happy path | Auth (401/403) | Validation (422) | Edge cases |
|---|---|---|---|---|
| Resource creation (POST) | 1 test each | 2 tests each | 3–5 tests each | 2–3 tests each |
| Resource reads (GET) | 1 test each | 1–2 tests each | 1 test (404) | 1 test (empty arrays) |
| Updates (PUT/PATCH) | 1 test each | 2 tests each | 3–4 tests each | partial update cases |
| Deletes (DELETE) | 1 test each | 2 tests each | 1 test (404) | idempotency check |
For 34 endpoints, this generates approximately 180–220 test cases covering all documented behavior. The spec's example values seed the happy path; required fields drive the 422 validation tests; security schemes drive the 401/403 tests; maxLength, minLength, pattern, and enum constraints drive the edge cases.
Run the suite with:
npm test -- --testPathPattern=tests/api
# With coverage:
npm test -- --testPathPattern=tests/api --coverage --collectCoverageFrom='src/**/*.ts'
Get Started
How to install and use this skill in your preferred environment.
Skills are designed for AI coding agents (Claude Code, Cursor, Windsurf) and IDE-based workflows where the agent can read files, run scripts, and act on your codebase.
Models & Context
Which AI models and context windows work best with this skill.
Recommended Models
Larger models produce more detailed, production-ready outputs.
Context Window
This skill's SKILL.md is typically 3–10 KB — fits in any modern context window.
All current frontier models support 100K+ context.
Pro tips for best results
Be specific
Include numbers — users, budget, RPS — so the skill can size the architecture.
Share constraints
Compliance needs, team size, and existing stack all improve the output.
Iterate
Start with a high-level design, then ask follow-ups for IaC, cost analysis, or security review.
Combine skills
Pair with companion skills below for end-to-end coverage.
Ready to try API Test Suite Builder?
Install the skill and start getting expert-level guidance in your workflow — any agent, any IDE.
Install for