The Tests Tab — Writing Your First Assertion

8 min read

Up to this point you've been a user of Postman — sending requests, reading responses, organising collections. This lesson promotes you to a tester. The Tests tab is where Postman stops being a request-builder and starts being an automated assertion engine. You'll write a few lines of JavaScript that run after every response, and Postman will tell you pass or fail in green or red. You learned the concepts of API assertions in the API Testing Masterclass — this lesson teaches you to drive them in Postman.

Where tests live

Open any saved request and click the Tests tab (the rightmost tab in the request builder, after Pre-request Script). You'll see an empty JavaScript editor. Anything you write here runs after the response is received and has access to the full response — status, headers, body — through Postman's pm object.

The editor's right sidebar lists Snippets: ready-to-paste templates for the most common assertions. Click any snippet and it inserts at the cursor. New testers should use snippets liberally; you'll outgrow them in a week.

Your first assertion

Open GET All Users from your JSONPlaceholder API Tests collection. Click the Tests tab. Paste:

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

Click Send. Then look at the response panel at the bottom and click the Test Results tab. You should see:

✓ Status code is 200

A green tick. Your first automated test in Postman, passing.

What just ran? pm.test() is the test wrapper. The first argument is a name (shown in the results); the second is a function that contains assertions. pm.response.to.have.status(200) is the assertion itself — it throws if the response status isn't 200, and pm.test catches the throw and records the test as failed. No throw, no failure, test passes.

Multiple tests per request

A single request can have many tests. Stack them in the Tests tab:

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});
 
pm.test("Response time is under 500ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(500);
});
 
pm.test("Response is JSON", function () {
    pm.response.to.be.json;
});
 
pm.test("Response is an array of users", function () {
    const body = pm.response.json();
    pm.expect(body).to.be.an("array");
    pm.expect(body.length).to.be.above(0);
});

Send. The Test Results tab now shows four results, one per pm.test block. Each test is independent — if one fails, the others still run. That's why you split assertions into named tests rather than stuffing them into one block: you want to know which property failed, not just that "something" did.

The end-to-end rhythm

Step back and look at the lifecycle Postman walks through every time you click Send.

Step 1 of 5

Write tests in the Tests tab

Add pm.test() blocks for each property of the response you want to assert. The script doesn't execute yet — it's just stored on the request.

That five-step rhythm is the entire mental model. Master it once and the rest of this chapter is just learning new assertions.

The pm object — what's available

Inside a Tests script, the pm object exposes the runtime. The pieces you'll use most:

  • pm.response — the full response.
    • pm.response.code — numeric status (200, 404…).
    • pm.response.status — reason phrase ("OK", "Not Found").
    • pm.response.responseTime — milliseconds.
    • pm.response.responseSize — bytes.
    • pm.response.headers.get("Content-Type") — read a single header.
    • pm.response.json() — parse the body as JSON. Throws if not JSON.
    • pm.response.text() — body as a raw string.
  • pm.expect(value) — Chai-style assertion. Chain matchers off it:
    pm.expect(value).to.equal(expected);
    pm.expect(value).to.be.a("string");
    pm.expect(array).to.include(item);
    pm.expect(object).to.have.property("name");
    pm.expect(num).to.be.below(100);
  • pm.response.to.have.status(200) — shorthand for pm.expect(pm.response.code).to.equal(200).
  • pm.environment.get/set, pm.collectionVariables.get/set — read and write variables (lesson 3 of this chapter, and Chapter 4 use these heavily).
  • pm.request — the request that was just sent (URL, method, body). Less common in tests; useful in pre-request scripts.

Snippets you should know by name

The right-hand snippet panel is your training wheels. The five you'll reach for repeatedly:

  • Status code: Code is 200 — the basic status assertion.
  • Response body: JSON value check — parses the body and asserts on a field.
  • Response body: Contains string — string-search inside the raw body.
  • Response headers: Content-Type header check — the standard JSON content-type assertion.
  • Response time is less than 200ms — the latency budget assertion.

After a week of writing tests, you won't need the snippets — but they're a perfect crib sheet while you're learning the syntax.

A complete first-test set

Here's a five-test template you can paste onto any GET that returns an array of objects (e.g. JSONPlaceholder's /users):

pm.test("Status is 200", () => {
    pm.response.to.have.status(200);
});
 
pm.test("Response time is under 500ms", () => {
    pm.expect(pm.response.responseTime).to.be.below(500);
});
 
pm.test("Content-Type is JSON", () => {
    pm.expect(pm.response.headers.get("Content-Type")).to.include("application/json");
});
 
pm.test("Body is a non-empty array", () => {
    const body = pm.response.json();
    pm.expect(body).to.be.an("array");
    pm.expect(body.length).to.be.above(0);
});
 
pm.test("First item has expected fields", () => {
    const first = pm.response.json()[0];
    pm.expect(first).to.have.property("id");
    pm.expect(first).to.have.property("name");
    pm.expect(first).to.have.property("email");
});

Five small tests; each one fails loudly if its specific concern breaks. That's the shape every endpoint test in this course will take.

Failure, on purpose

Change the status assertion to expect 999:

pm.test("Status is 999", () => {
    pm.response.to.have.status(999);
});

Send. The Test Results tab now shows a red next to that test with the failure message:

✗ Status is 999
  AssertionError: expected response to have status code 999 but got 200

That's exactly what you'd see when a real assertion breaks. Always change a test once to make it fail before trusting it — a passing test you've never seen fail might just be never running.

⚠️ Common mistakes

  • Calling pm.response.json() on a non-JSON response. It throws and your test errors out (not just fails — errors). Guard with pm.expect(pm.response.headers.get("Content-Type")).to.include("application/json") first, or wrap in try/catch.
  • Naming every test "Test 1", "Test 2". The test name is what shows up when something fails at 3am. Name each test after the property it's protecting: "Status is 200", "Body is array", "Email field present".
  • Stuffing every assertion into one pm.test() block. When a single block has five expects and one fails, the rest don't run and you only see the first failure. Split into one pm.test() per logical concern.

🎯 Practice task

Write your first test suite. 25-30 minutes.

  1. Open GET All Users in your collection. Paste the five-test template from earlier into the Tests tab. Send. Confirm all five pass.
  2. Open GET User by ID (/users/1). Adapt the five-test template — the body is now a single object, not an array. Change pm.expect(body).to.be.an("array") to pm.expect(body).to.be.an("object"), and replace the array length check with field assertions on the object directly.
  3. Open POST Create Post. Add three tests: status is 201, body has property id, and id is a number.
  4. Open DELETE Post. Add two tests: status is 200 (JSONPlaceholder returns 200 for DELETE; a strict API would return 204), and response body is an empty object.
  5. Break a test on purpose. Change one of the status assertions to expect 999. Send. See the red failure message in the Test Results tab. Change it back.
  6. Use a snippet. In any Tests editor, click the right-hand panel → Response time is less than 200ms. Notice it inserts a complete pm.test block ready to use.
  7. Stretch: add a sixth test to GET All Users that asserts every user object has both an id and an email. Use body.forEach(...) inside one pm.test.

You can now write Postman tests with confidence. The next lesson goes deeper into the three big assertion families — status, body, and headers — and the patterns that hold up across real APIs.

// tip to track lessons you complete and pick up where you left off across devices.