API Testing Guide

What to Test in Every API Endpoint

CategoryTest Cases
Happy pathValid input → expected response body, correct status code
ValidationMissing required fields, wrong types, boundary values
AuthenticationNo token → 401, expired token → 401, invalid token → 401
AuthorizationCorrect user but wrong role → 403, access other user's data → 403
Not foundNon-existent ID → 404
IdempotencyRepeated POST with same key → same result, no duplicate
ConcurrencyRace conditions on shared resources
Response schemaAll expected fields present, correct types

Integration Tests with Supertest (Node.js)

import request from 'supertest'; import app from '../app'; import { db } from '../db'; describe('POST /api/users', () => { afterEach(() => db.users.deleteMany({})); // clean up it('creates a user and returns 201', async () => { const res = await request(app) .post('/api/users') .send({ name: 'Alice', email: 'alice@example.com' }) .expect(201) .expect('Content-Type', /json/); expect(res.body).toMatchObject({ id: expect.any(String), name: 'Alice', email: 'alice@example.com', createdAt: expect.any(String) }); }); it('returns 400 when email is missing', async () => { const res = await request(app) .post('/api/users') .send({ name: 'Alice' }) .expect(400); expect(res.body.error).toContain('email'); }); it('returns 409 when email already exists', async () => { await db.users.create({ name: 'Alice', email: 'alice@example.com' }); await request(app) .post('/api/users') .send({ name: 'Bob', email: 'alice@example.com' }) .expect(409); }); });

Newman (CLI) & Postman Automation

# Run Postman collection from CLI newman run collection.json \ --environment staging.env.json \ --reporters cli,json \ --reporter-json-export results.json # In CI/CD (GitHub Actions) # - name: Run API tests # run: | # newman run tests/api-collection.json \ # --env-var "BASE_URL=${{ env.API_URL }}" \ # --env-var "API_KEY=${{ secrets.API_KEY }}" # Postman test script example (in Tests tab) pm.test("Status code is 200", () => { pm.response.to.have.status(200); }); pm.test("Response schema is valid", () => { const schema = { type: "object", required: ["id", "name", "email"], properties: { id: { type: "string" }, name: { type: "string" }, email: { type: "string", format: "email" } } }; pm.response.to.have.jsonSchema(schema); }); // Save token for subsequent requests const token = pm.response.json().token; pm.environment.set("AUTH_TOKEN", token);