After this lesson, you will be able to: Test REST APIs with Postman collections, automated API tests (Supertest), and load tests (k6).
API tests catch contract drift before it hits clients. Three layers: manual (Postman), automated (Supertest), load (k6). Production teams use all three.
Manual + scriptable test runs.
// In Postman: build a collection with requests per endpoint.// Add tests in the Tests tab of each request:pm.test('Status is 200', () => {pm.response.to.have.status(200);});pm.test('Has expected fields', () => {const body = pm.response.json();pm.expect(body).to.have.property('id');pm.expect(body.email).to.match(/@/);});// Export collection + run in CI with Newman:// npx newman run my-collection.json --env-var TOKEN=$TOKEN
Hit your Express app in-process; no HTTP overhead.
// npm i -D supertest vitestimport request from 'supertest';import { describe, it, expect } from 'vitest';import { app } from '../src/app';describe('POST /users', () => {it('creates a user', async () => {const res = await request(app).post('/users').expect('Content-Type', /json/).expect(201);expect(res.body).toHaveProperty('id');});it('returns 422 on invalid email', async () => {const res = await request(app).post('/users').send({ email: 'not-an-email', name: 'A' }).expect(422);expect(res.body.error).toBe('ValidationError');});});
JavaScript-scripted load tests.
// k6 test script, load-test.jsimport http from 'k6/http';import { check, sleep } from 'k6';export const options = {stages: [{ duration: '30s', target: 20 }, // ramp to 20 users{ duration: '1m', target: 20 }, // hold 20 users{ duration: '30s', target: 100 }, // spike to 100{ duration: '30s', target: 0 }, // ramp down],thresholds: {http_req_duration: ['p(95)<300'], // 95% under 300mshttp_req_failed: ['rate<0.01'], // < 1% errors},};export default function () {const res = http.get('https://api.example.com/users');check(res, {'status is 200': (r) => r.status === 200,'body has data': (r) => r.json('length') > 0,});sleep(1);}// k6 run load-test.js
Pact (consumer-driven contracts): client defines what it expects; provider runs those tests against itself. Prevents breaking changes catching either side off-guard. Schemathesis: generates property-based tests from your OpenAPI spec. Catches edge cases you didn't think of. Use these when you have multiple teams sharing an API.
No tests on error paths (only happy path). Tests that hit the real DB without isolation (flaky). Skipping load testing until prod blows up. Postman collection that lives on one dev's laptop (export + commit to repo).
Sign in and purchase access to unlock this lesson.