Postman
Postman
Definition: The most widely used tool for manually testing, documenting, and automating tests against APIs, built around a graphical interface for sending HTTP requests and a JavaScript-based scripting layer for asserting on responses.
How It Works
- A request is built visually: method, URL, headers, query params, body (JSON, form data, raw text), then sent with one click, showing the raw response, status code, headers, and timing.
- Collections group related requests into a saved, shareable, runnable set, effectively a folder of API calls that mirrors a real API’s structure.
- Environments hold variable sets (
{{baseUrl}},{{authToken}}) that swap in per context (local, staging, production) without editing the requests themselves. - Variable scopes stack: global, environment, collection, and local variables all resolve in a defined precedence order, so the same request can behave differently depending on which environment is active.
- Pre-request scripts run before a request is sent, JavaScript that can compute a signature, set a timestamp, or refresh a token, and write it into a variable the request then uses.
- Test scripts run after the response arrives, using
pm.test()blocks and Chai-stylepm.expect()assertions to check status codes, headers, and body content. - Variables can be written from one request’s response and read by the next (
pm.environment.set('token', response.token)), letting a collection chain requests: log in, capture the auth token, use it on every following request. - The Collection Runner executes every request in a collection in order, running each one’s test scripts and producing a pass/fail summary, useful for regression-testing an entire API surface at once.
- Newman is Postman’s CLI runner: it executes an exported collection headlessly, exactly the pre-request and test scripts, from a terminal or a CI pipeline, with no GUI involved.
- Mock servers can be generated directly from a collection, returning example responses defined in the collection, useful for developing a frontend before the real backend endpoint exists.
- Postman also validates responses against an OpenAPI/JSON Schema definition if one is attached, catching structural drift even without writing a single explicit assertion.
Under the Hood
Given a login request whose token is needed by every later request Step:
// Test script on the "Login" request
pm.test("Login succeeded", function () {
pm.response.to.have.status(200);
});
const body = pm.response.json();
pm.environment.set("authToken", body.token);
// Used on later requests, in the Headers tab
Authorization: Bearer {{authToken}}
Answer: The test script asserts the login itself worked, then stores the returned token into the current environment. Every subsequent request in the collection reads {{authToken}} from that same environment, so the whole chain runs without hardcoding a token anywhere.
Given a response that should return a specific JSON shape Step:
pm.test("Response has expected fields", function () {
const json = pm.response.json();
pm.expect(json).to.have.property("id");
pm.expect(json.status).to.eql("active");
pm.expect(pm.response.responseTime).to.be.below(500);
});
Answer: Three independent checks run in one test block: field presence, an exact value match, and a performance budget. If any fails, Postman reports that specific assertion’s message, not just “test failed.”
Because each pm.test() call is independent, one failing assertion doesn’t stop the others from running, so a single request can surface multiple distinct problems in one pass.
Why It Matters
- Lets a developer explore and debug an API interactively before writing any automated test code, catching integration issues early.
- Attaching an OpenAPI schema for validation catches contract drift (a field renamed, a type changed) automatically, without hand-writing an assertion for every field.
- Collections double as living documentation: a well-organized collection shows exactly what requests an API supports and what a real response looks like.
- Automating collections through Newman turns manual exploration into a real regression suite that runs in CI on every deploy, not just a one-off GUI exercise.
- Chained requests with environment variables mean realistic multi-step flows (auth, then a resource call) can be tested end-to-end without external scripting.
- Mock servers let frontend and backend teams work in parallel, the frontend builds against the mocked contract while the real endpoint is still being implemented.
Common Pitfalls
- Hardcoding URLs, tokens, or IDs directly into requests instead of environment variables, making a collection break the moment it’s run against a different environment.
- Asserting only on the status code and skipping the response body, missing regressions where a
200comes back with wrong or missing data. - Committing collections with real secrets (API keys, tokens) baked in instead of using environment variables and a
.gitignored local environment file. - Relying entirely on manual clicking through the UI and never wiring the collection into Newman/CI, so regressions aren’t caught until someone happens to test by hand.
- Building brittle request chains where request 5 silently depends on state set by request 2, so running requests out of order or in isolation fails confusingly.
- Editing a shared team collection directly instead of using version control or Postman’s built-in fork/merge workflow, causing untracked changes to overwrite each other.
- Not setting timeouts or performance assertions, letting a slow endpoint pass every functional check while quietly degrading.
- Duplicating the same assertion logic across dozens of requests by copy-paste instead of using a collection-level pre-request/test script that runs for every request automatically.
Comparison
| Postman | Insomnia | curl | REST Assured | |
|---|---|---|---|---|
| Interface | GUI, collections, environments | GUI, similar collection model | Command line only | Code (Java library) |
| Scripting/assertions | JavaScript, pm.test/pm.expect | JavaScript, similar model | None built in | Java, integrates with JUnit/TestNG |
| CI automation | Newman CLI runner | inso CLI runner | Shell scripts | Runs as part of the normal Java test suite |
| Best fit | Manual exploration plus automatable collections | Lightweight GUI alternative to Postman | Quick one-off requests, scripting | API tests written by developers alongside app code |
| Mocking | Built-in mock servers from a collection | Built-in mock servers | None built in | None built in |
Example
# Run a collection headlessly with Newman, in CI
newman run api-tests.postman_collection.json \
-e staging.postman_environment.json \
--reporters cli,junit \
--reporter-junit-export results.xml
// Inside the collection: a test on a GET /users/:id request
pm.test("Status code is 200", () => pm.response.to.have.status(200));
pm.test("User has an email field", () => {
pm.expect(pm.response.json()).to.have.property("email");
});
Newman runs the exported collection exactly as Postman would, against the staging environment, and writes a JUnit-format report that CI systems already know how to parse and display.
A failing pm.test gives Newman a non-zero exit code, which is what actually fails the CI job, not just a red line in a report nobody reads.
Related Terms
- REST API — what Postman requests and asserts against
- HTTP Methods — the verbs (GET, POST, PUT, DELETE) every Postman request is built around
- HTTP Status Codes — the primary thing
pm.testblocks assert on - JWT (JSON Web Token) — commonly captured into an environment variable after a login request
- k6 — picks up where Postman’s functional tests stop, for load and performance testing
- CI-CD — where Newman-run collections typically execute on every deploy
- GraphQL — Postman supports GraphQL requests alongside REST, with the same test-script layer
- OAuth 2.0 — a common pre-request script scenario is refreshing an OAuth token before each run
Referenced by