Writing Tests & Scripts
pm.test and pm.expect assertions on status codes, headers, bodies and response times, plus pre-request scripts.
Where scripts run
Postman runs JavaScript at two points for every request:
- Pre-request script — runs before the request is sent: generate data, set variables, compute signatures.
- Post-response script (the Tests / Scripts → Post-response tab) — runs after the response arrives: assertions and saving values for later requests.
Scripts can also be added at the folder and collection level, where they run for every request inside.
Your first test
Add this to the post-response script of GET {{baseUrl}}/posts/1 (with baseUrl = https://jsonplaceholder.typicode.com):
pm.test('Status code is 200', () => {
pm.response.to.have.status(200);
});
pm.test('Response is JSON', () => {
pm.response.to.be.json;
});
pm.test('Post has the expected shape', () => {
const post = pm.response.json();
pm.expect(post.id).to.eql(1);
pm.expect(post.userId).to.be.a('number');
pm.expect(post.title).to.be.a('string').and.not.be.empty;
});
pm.test('Responds in under 800 ms', () => {
pm.expect(pm.response.responseTime).to.be.below(800);
});
Click Send and open the Test Results tab: each pm.test shows as pass or fail.
The pm API essentials
| Code | Purpose |
|---|---|
pm.response.code |
Status code (number) |
pm.response.to.have.status(201) |
Assert status |
pm.response.json() |
Parsed JSON body |
pm.response.text() |
Raw body |
pm.response.headers.get('Content-Type') |
Header value |
pm.response.responseTime |
Time in ms |
pm.expect(value) |
Chai assertion |
pm.test(name, fn) |
Named test |
Common assertions
const body = pm.response.json();
// Status and headers
pm.test('201 Created', () => pm.response.to.have.status(201));
pm.test('JSON content type', () => {
pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');
});
// Values
pm.test('Title saved', () => pm.expect(body.title).to.eql('Testing with Postman'));
pm.test('Has an id', () => pm.expect(body).to.have.property('id'));
// Arrays
pm.test('Returns comments for post 1 only', () => {
const comments = pm.response.json();
pm.expect(comments).to.be.an('array').that.is.not.empty;
comments.forEach((c) => pm.expect(c.postId).to.eql(1));
});
// Contains an item
pm.test('Includes a known email', () => {
const emails = pm.response.json().map((c) => c.email);
pm.expect(emails).to.include('Eliseo@gardner.biz');
});
The array tests above work against GET {{baseUrl}}/comments?postId=1.
Negative tests
Good API testing checks error responses as carefully as successes:
// GET {{baseUrl}}/posts/99999
pm.test('Unknown post returns 404', () => {
pm.response.to.have.status(404);
});
For your own APIs, also test: missing required fields (expect 400/422 with a clear message), wrong data types, unauthorised requests (401), forbidden actions (403), duplicate creation (409) and very large payloads (413). The REST API status codes lesson explains which codes to expect.
Pre-request scripts: generating data
Avoid hard-coded test data that collides between runs:
// Pre-request script on "POST Create post"
const stamp = Date.now();
pm.variables.set('postTitle', `QA post ${stamp}`);
pm.variables.set('randomEmail', `qa.${stamp}@example.com`);
{
"title": "{{postTitle}}",
"body": "Created by a pre-request script",
"userId": 1
}
Postman also has built-in dynamic variables for quick random data: {{$randomFirstName}}, {{$randomEmail}}, {{$guid}}, {{$timestamp}}, {{$randomInt}}.
Collection-level tests
Checks that apply to every request — like "never take longer than 2 seconds" or "always return JSON" — belong in the collection's post-response script, so you write them once:
// Collection → Scripts → Post-response
pm.test(`[${pm.info.requestName}] responds within 2s`, () => {
pm.expect(pm.response.responseTime).to.be.below(2000);
});
pm.info.requestName makes failures easy to trace in reports.
Debugging scripts
Use console.log() and open the Postman Console:
console.log('Status', pm.response.code);
console.log('Body', pm.response.json());
Next: passing data between requests with Variables & Request Chaining.