Build the mental model
A Postman collection groups related requests into one organized unit — a "Users API" collection holding List, Get, Create, Update, and Delete side by side, instead of five disconnected tabs. This makes a whole API easy to hand to a teammate or return to months later.
A single successful call only proves the happy path. Real testing means thinking like someone trying to break the API on purpose, not just confirming it works once under ideal conditions.
- Missing required input — e.g. creating a user without sending the required "name" field.
- Invalid or expired token — e.g. sending a malformed token or one past its lifetime.
- Forbidden access — e.g. a logged-in but unprivileged user hitting an admin-only endpoint.
- Resource not found — e.g. requesting a user ID that was never created or was deleted.
- Duplicate data — e.g. creating an account with an email address already in use.
- Rate limited — e.g. sending far more requests than the API allows within a minute.
- Server failure — e.g. the API itself returning a 500 due to an internal error.
A request can carry several of these test cases attached to it — one confirming success, several confirming failures, each checking a specific status code or response shape. That turns "does it work" into a far more useful question: does it fail the way it should, in every situation that matters.
USERS API COLLECTION TREE
-------------------------
USERS API COLLECTION
|-- List Users GET /users
|-- Get User GET /users/:id
|-- Create User POST /users
| +-- test: valid data -> 201 Created
| +-- test: missing name -> 400 Bad Request
| +-- test: invalid token -> 401 Unauthorized
| +-- test: duplicate email -> 409 Conflict
|-- Update User PUT /users/:id
+-- Delete User DELETE /users/:idConnect it to a real scenario
Picture the Users API collection with its five requests: List, Get, Create, Update, Delete. Under Create, a happy-path case confirms 201 on valid data, plus failure cases: an empty body returns 400, a missing token returns 401, and a duplicate email returns 409 instead of silently duplicating the account.
Under Get, a nonexistent user ID should return 404, not 200 with empty data. Under Delete, calling it twice on the same ID should behave predictably, not crash. None of these are exotic — they're situations real clients hit constantly.
What the code below does
A small mock "server" behaving by rules like these, plus a batch of test cases — most passing, one deliberately wrong — run against it to produce a pass/fail report, the same shape a real Postman test run produces.
Try the working example
// Mock "Users API" responder — pretends to be the server the
// collection targets.
function mockUsersApi(request) {
const { method, path, headers = {}, body } = request;
if (method === "GET" && path === "/users/1") {
return { status: 200, body: { id: 1, name: "Aye Aye" } };
}
if (method === "POST" && path === "/users") {
if (!body || !body.name) {
return { status: 400, body: { error: "name is required" } };
}
if (headers.Authorization !== "Bearer valid-token") {
return { status: 401, body: { error: "invalid or missing token" } };
}
return { status: 201, body: { id: 99, name: body.name } };
}
if (method === "DELETE" && path === "/users/1") {
return { status: 403, body: { error: "not allowed" } };
}
return { status: 404, body: { error: "not found" } };
}
// Each test case: a request plus what we expect back.
const testCases = [
{
name: "Get existing user (happy path)",
request: { method: "GET", path: "/users/1" },
expectedStatus: 200,
},
{
name: "Create user with missing name",
request: { method: "POST", path: "/users", body: {} },
expectedStatus: 400,
},
{
name: "Create user with invalid token",
request: {
method: "POST",
path: "/users",
headers: { Authorization: "Bearer wrong-token" },
body: { name: "Su Su" },
},
expectedStatus: 401,
},
{
name: "Delete user without permission",
request: { method: "DELETE", path: "/users/1" },
expectedStatus: 403,
},
{
name: "Get a user that does not exist",
request: { method: "GET", path: "/users/404" },
expectedStatus: 404,
},
{
// Deliberately wrong expectation, to show a realistic failing report.
name: "Create user with valid token (wrong expectation on purpose)",
request: {
method: "POST",
path: "/users",
headers: { Authorization: "Bearer valid-token" },
body: { name: "Zaw Zaw" },
},
expectedStatus: 200, // actual API returns 201 Created
},
];
function runTestCases(cases, responder) {
const results = cases.map((testCase) => {
const response = responder(testCase.request);
const passed = response.status === testCase.expectedStatus;
return {
name: testCase.name,
expectedStatus: testCase.expectedStatus,
actualStatus: response.status,
passed,
};
});
const passedCount = results.filter((r) => r.passed).length;
return {
results,
summary: `${passedCount}/${results.length} test cases passed`,
};
}
const report = runTestCases(testCases, mockUsersApi);
report.results.forEach((r) => {
const mark = r.passed ? "PASS" : "FAIL";
console.log(
`[${mark}] ${r.name} (expected ${r.expectedStatus}, got ${r.actualStatus})`
);
});
console.log(report.summary);Actual output when run:
[PASS] Get existing user (happy path) (expected 200, got 200)
[PASS] Create user with missing name (expected 400, got 400)
[PASS] Create user with invalid token (expected 401, got 401)
[PASS] Delete user without permission (expected 403, got 403)
[PASS] Get a user that does not exist (expected 404, got 404)
[FAIL] Create user with valid token (wrong expectation on purpose) (expected 200, got 201)
5/6 test cases passed
The one failure is intentional: the mock API correctly returns 201 Created for a successful creation, but the test case was written expecting 200 — exactly the kind of mismatch a real test suite catches.5-minute try-it
Pick one endpoint from an API you've used before. Write out at least four test cases for it: the happy path, plus three of the seven failure categories from this lesson. Be specific about the exact status code you'd expect for each one before you'd consider that test case passing.
One important caution
Testing only the happy path and calling it "tested" — most real bugs surface in the failure cases, not the one success case.
Writing a test case that only checks a request didn't throw, instead of asserting a specific status code or field — that catches almost nothing.
Postman Docs — Collections Overview — API Integration & Webhooks