skip to content

Named Test Blocks

The unit a verdict is reported in: a named block wrapping your checks that yields one pass, fail or skip however many claims sit inside. Interviewers ask what happens when one throws.

part ofAPI & DB clientsoverview, primer and where to startread it →
on this pageshow

explore

questions

5

In a Postman script, how many results does one pm.test block containing five pm.expect calls report?

level: middleimportance: must knowfreq 76%

answer

  1. The block is the reporting unit
  2. One record regardless of expectation count
  3. Single error slot, single passed flag
  4. First throw unwinds the rest
  5. name, passed, skipped, error, index

basics

~20 s

Exactly one. A pm.test block is the reporting unit: it emits a single record carrying a name, a passed flag, a skipped flag, an error slot and an index, however many pm.expect calls sit inside it.

solid answer

~40 s

One. `pm.test(name, fn)` builds a single assertion record and then runs `fn` inside a try/catch; the record is emitted once, when the block finishes. Its fields are `name`, `passed`, `skipped`, `error`, `index` and `async` — there is one `error` slot and one `passed` flag, not a list. So five `pm.expect` calls in one block collapse into one pass or one fail. Because the body is a single try, the **first** throw unwinds the rest of the function: the later expectations never execute and the record carries only the first error. If you want each claim reported separately, write a separate `pm.test` block per claim and name each block after the claim it makes.

code

javascript · 5 lines
javascript
pm.test('order is created', function () {
    pm.expect(pm.response.code).to.eql(201);
    pm.expect(pm.response.json().id).to.be.a('string');
    pm.expect(pm.response.json().total).to.be.above(0);
});

go deeper

for a junior

Recall that a check lives inside pm.test(name, fn) and that the name you pass is what shows up in the report. Know that one block equals one reported line.

for a middle

Explain the record's fields — name, passed, skipped, error, index — and why a single try/catch means the first throw skips the rest of the body. Be able to say when to split blocks.

for a senior

Show judgment about granularity: which claims deserve their own line, how naming makes a failure diagnosable from the report alone, and why ordering inside a block decides what a failing run tells you.

for a principal

Own the convention across a collection: a naming scheme that survives the failure roll-up, a house rule on block granularity, and the tradeoff between report resolution and script volume.

## The block, not the expectation, is the unit `pm.test(name, fn)` is the function the Postman sandbox exposes for writing a check. Calling it does exactly two things: it builds **one assertion record**, and it invokes `fn`. The record is handed to the sandbox's assertion channel once, when the block finishes. However many `pm.expect(...)` calls the body holds — one, five, or fifty — the reporting surface sees a single line for that block. That split is the whole design. `pm.expect(...)` is an assertion-library call: it throws when the claim is false and returns nothing interesting when it is true. On its own a throw is just an error. It is `pm.test` that converts "did the body throw or not" into a **named, numbered, reportable verdict** that something outside the script can count. ## What one record carries The sandbox builds the record *before* it runs your function, so the block has an identity even if the body explodes on its first line: | field | what the sandbox puts there | |---|---| | `name` | the first argument, coerced with `String(name)` | | `passed` | `true` unless the body threw, or an async callback was handed an error | | `skipped` | `true` only for a block created by `pm.test.skip` | | `error` | the thrown value, or `null` | | `index` | a counter starting at `0` for each script execution, incremented per block | | `async` | `true` when the block's function declared a callback parameter | Notice what is **absent**: there is no count of expectations, no array of errors, no per-assertion breakdown. One `error` slot. One `passed` flag. That is the resolution at which a Postman script reports, and it is fixed by the shape of this record — no amount of extra `pm.expect` calls raises it. ## The first throw ends the body The synchronous form runs your function inside a single try/catch. That has a consequence people underestimate: the **first** failing expectation unwinds the rest of the function. Imagine one block that checks the status code, then a header, then three fields of the payload. The service returns a `500` with an error page. The status expectation throws, and: - the header check never runs; - the three payload checks never run; - the record's `error` holds the status failure and nothing else; - the report shows one failed line, so a reader cannot tell whether the payload was also wrong. Ordering inside a block is therefore load-bearing. Put the cheapest and most fundamental claim first, because everything after it is conditional on it. A block that asserts a body field before asserting the status code will report a confusing `undefined` error whenever the call fails outright. ## Sizing a block There is no rule that forces one expectation per block, so the choice is yours to justify: 1. **One claim, one block** when you want each claim's verdict reported on its own line and want the report to say which claim broke without anyone opening the run. 2. **Several expectations in one block** when they are only meaningful together — narrowing a value after proving the field exists, for example, where reporting the second failure separately would be noise. 3. **Never** wrap an entire response's worth of unrelated claims in a single block named after the request. You get one bit of information back for a lot of code. ## Names are the handle a reader gets The name is not decoration. The Postman runtime collects the names of blocks whose `passed` is `false` and joins them into one error it labels `AssertionFailure`. That joined string is often all a reader sees first. A block named `"Test 1"` tells them nothing; `"status is 201"` tells them what broke before they open anything. Two blocks sharing a name are indistinguishable in that roll-up, so names should be unique within a script. ## The counter `index` is assigned when the block starts, not when it finishes, and the counter is per script execution — a pre-request script and a test script each start their own numbering at `0`. `pm.test.index()` returns the current value, i.e. how many blocks have been created so far in this execution. It is a position, not a score: it says nothing about pass or fail.

  • If the second of five expectations in one block fails, what does the record say about the remaining three?
    Nothing. The body runs in one try/catch, so the throw unwinds the function and expectations three through five never execute. The record carries `passed: false` and the single first error. The report cannot distinguish "the rest were fine" from "the rest were never attempted", which is the main cost of grouping.
  • What does pm.test.index() return, and is it a count of passing blocks?
    It returns the block counter for the current script execution — how many assertion records have been created so far, starting from `0`. It counts blocks, not successes: failed and skipped blocks increment it exactly like passing ones. Each script execution starts its own numbering, so a pre-request script's indices do not continue into the test script.

A pm.test block is a ballot box, not a ballot: however many votes you drop in, the outside world reads one result off the lid.

saying these in an interview costs you the question

  • Claims each pm.expect call produces its own reported result
  • Believes all expectations run even after one throws
  • Thinks the record holds a list of every error raised
  • Names blocks Test 1, Test 2 with no claim in the name
  • Puts a payload-field check before the status-code check
open as a page

In a Postman test script, how does a throw inside a pm.test block differ from a throw outside one?

level: middleimportance: must knowfreq 68%

basics

~20 s

Containment. A throw inside pm.test is caught by that block: the block is recorded as failed and the script keeps going. A throw outside any block escapes, ends the script execution and surfaces as an execution error, not an assertion.

open as a page

What does pm.test.skip do in a Postman script, and what does the block report?

level: juniorimportance: should knowfreq 44%

basics

~20 s

pm.test.skip(name) emits an assertion record for the named block without running any check. The record has skipped set to true, and its passed flag stays true, so a consumer that reads only passed sees a skip as a pass.

open as a page

When does a Postman pm.test block report no result at all, and why would a script hide a check that way?

level: seniorimportance: should knowfreq 36%

basics

~20 s

When the block's function declares a callback parameter and never calls it. That switches pm.test to its asynchronous form, where the record is emitted only by that callback, so an uncalled callback leaves the block absent.

open as a page

In a Postman script, what does pm.test record when its second argument is missing or is not a function?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

A pass. pm.test checks whether the second argument is a function; when it is not, the sandbox emits the block's record immediately with passed true and no error, so a check with no body reports green without testing anything.

open as a page