skip to content

In a Postman test script, how does `statusCodeClass` differ from asserting an exact code with `status`?

level: middleimportance: should knowfreq 45%

answer

  1. It looks at one digit only
  2. Several codes satisfy the same assertion
  3. The failure text names a class, not a code
  4. Named shorthands exist on the be chain
  5. Looser on purpose, and looser has a cost

basics

~20 s

Postman's statusCodeClass matcher compares only the leading digit of the reply's status code, so statusCodeClass(2) accepts any code from 200 to 299. The status matcher with a number demands that exact code and nothing else.

solid answer

~40 s

`pm.response.to.have.statusCodeClass(2)` reads the reply's numeric code and compares **only its leading digit**, so 200, 201 and 204 all satisfy it. `pm.response.to.have.status(201)` demands exactly 201. The failure text makes the difference visible: a class assertion reports `expected response code to be 1XX but found 200`, naming a class rather than a code. Named shorthands for the same leading-digit check exist on the `be` chain — `pm.response.to.be.success`, `pm.response.to.be.clientError` — and read better when the class is the whole point. What each class *means* on the wire is HTTP's business, not the matcher's; the matcher only compares a digit. Use the class form when several codes are legitimately acceptable, and the exact form when the code is part of the contract you are testing.

code

javascript · 2 lines
javascript
pm.response.to.have.statusCodeClass(2);
pm.response.to.have.status(201);

go deeper

for a junior

Recall that statusCodeClass takes a single digit and accepts any code beginning with it, while status with a number demands that exact code.

for a middle

Explain that only the leading digit is compared, recognise the class-shaped failure message, and know the named shorthands on the be chain that do the same comparison.

for a senior

Show you understand what looseness costs: a class assertion cannot catch a code regression within its own class, so decide per request whether the exact code is part of the contract under test.

for a principal

Own the convention across a suite estate: which endpoints must pin exact codes, where class checks are the honest choice, and how to stop teams widening assertions as a response to flakiness.

## What the matcher actually compares `statusCodeClass` sits on Postman's response assertion chain next to `status`, `statusCode` and `statusReason`. It takes a single digit and compares it with the **leading digit** of the reply's numeric status code. Nothing else is consulted: not the remaining two digits, not the reason phrase, not a header, not the payload. ```javascript pm.response.to.have.statusCodeClass(2); pm.response.to.have.status(201); ``` The first line passes for any code in the 200s. The second passes only for 201. When a class assertion fails, its message says so in class language — `expected response code to be 1XX but found 200` — which is a useful tell when you are reading someone else's failing run and trying to work out how tight the assertion was. ## Class versus exact code | Assertion | Passes for | Fails for | |---|---|---| | `status(201)` | 201 only | 200, 202, 204, everything else | | `statusCode(201)` | 201 only | 200, 202, 204, everything else | | `statusCodeClass(2)` | any code 200–299 | anything outside that range | | `status('Created')` | any reply whose reason phrase is Created | any other phrase | The last row is worth keeping in view because it is the other axis of looseness: `status` dispatches on argument type, so a string argument is a reason-phrase check rather than a code check. ## The named shorthands The same leading-digit comparison is available under names on the `be` chain, which reads more naturally when the class is the point of the assertion: - `pm.response.to.be.info` - `pm.response.to.be.success` - `pm.response.to.be.redirection` - `pm.response.to.be.clientError` - `pm.response.to.be.serverError` - `pm.response.to.be.error` These are matcher **names**, not explanations. What a given class signifies on the wire — which method should produce which code, when a body is expected, what a client should do next — is HTTP's semantics and belongs to protocol material, not to a Postman assertion. The matcher's whole job is a digit comparison. ## When each one is right 1. **Assert the exact code when the code is the contract.** If the endpoint is specified to answer 201 on creation and 204 on delete, a class assertion lets a regression from 201 to 200 sail through unnoticed. That is a real defect the test was supposed to catch. 2. **Assert the class when several codes are legitimately acceptable.** A read endpoint that may answer 200 or 206 depending on the request, or a suite pointed at more than one environment where the deployed behaviour differs, is better served by a class check than by an exact code that will be wrong somewhere. 3. **Assert the class in a broad smoke run.** When the goal is "nothing is on fire across sixty requests", pinning each exact code buys precision nobody uses and maintenance everybody pays for. 4. **Never use a class assertion to paper over a flaky endpoint.** Widening `status(201)` into `statusCodeClass(2)` because the test sometimes fails converts a signal into silence. Find out which other code is being returned and why. ## Reading a suite that mixes them A collection that uses class assertions everywhere is usually a smoke suite, and its green run means much less than it appears to. A collection that pins exact codes everywhere is precise but will need editing whenever a legitimate second code appears. Most healthy suites are mixed on purpose: exact codes on the handful of requests whose codes are specified in the contract, class checks on the long tail whose only requirement is not to have failed. When you inherit a suite, the mix tells you what the previous authors believed mattered. When you write one, be able to say for each assertion which of those two things you meant — because the difference between them is exactly the difference between a test that catches a code regression and a test that does not.

  • A creation endpoint silently changed from 201 to 200 and the suite stayed green. What was probably asserted?
    A class assertion — `statusCodeClass(2)` or the `success` shorthand — which compares only the leading digit, so 200 and 201 are indistinguishable to it. If the specified code is part of the contract, pin it with `status(201)` or `statusCode(201)`; keep the class form for requests where several codes are genuinely acceptable.
  • Is widening an exact-code assertion into a class assertion a reasonable fix for a flaky test?
    No. It removes the signal instead of the flakiness. If a request sometimes answers a different code, that is information about the API or the environment, and widening the assertion buries it. Find out which code appears and why, then decide deliberately whether both are acceptable.

saying these in an interview costs you the question

  • Reads statusCodeClass(2) as asserting the code equals 2
  • Thinks the matcher inspects the reason phrase too
  • Uses class assertions everywhere and calls the suite precise
  • Widens an exact assertion to silence a flaky test
  • Cannot say which codes a class assertion admits