Engineering Advanced APITestingAutomation

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.

You

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?

Agent

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)
  • nullable and example values 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

Best
Claude Opus 4.8 Claude Sonnet 4 GPT-4.1 Gemini 2.5 Pro Grok 3 Kimi K2
Good
Claude Haiku 4.5 GPT-4.1 mini Gemini 2.5 Flash Grok 3 mini

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.

8K Skill only
32K+ Skill + conversation
100K+ Skill + references + codebase

All current frontier models support 100K+ context.

Pro tips for best results

1

Be specific

Include numbers — users, budget, RPS — so the skill can size the architecture.

2

Share constraints

Compliance needs, team size, and existing stack all improve the output.

3

Iterate

Start with a high-level design, then ask follow-ups for IaC, cost analysis, or security review.

4

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

← Browse all skills