A Postman request without tests is just a fancy curl command. The whole point of a collection is automated validation. Every request should have at least 3 assertions: status code, response structure, and at least one business rule.
Layer 1: Status code — pm.response.to.have.status(200)
Layer 2: Response structure — check that expected fields exist and have correct types
Layer 3: Business logic — verify actual values, relationships, and constraints
// POST /api/register with only email, no password
// Body: { "email": "eve.holt@reqres.in" }
pm.test("Missing password returns 400", function() {
pm.response.to.have.status(400);
});
pm.test("Error message explains the problem", function() {
const response = pm.response.json();
pm.expect(response.error).to.eql("Missing password");
});
pm.test("No token is returned", function() {
const response = pm.response.json();
pm.expect(response.token).to.be.undefined;
});// GET /api/users/999
pm.test("Non-existent user returns 404", function() {
pm.response.to.have.status(404);
});
pm.test("Response body is empty object", function() {
const response = pm.response.json();
pm.expect(Object.keys(response)).to.have.lengthOf(0);
});// PUT /api/users/2
// Body: { "name": "Priya Updated", "job": "Lead SDET" }
pm.test("Update returns 200", function() {
pm.response.to.have.status(200);
});
pm.test("Updated name is reflected", function() {
const response = pm.response.json();
pm.expect(response.name).to.eql("Priya Updated");
});
pm.test("Updated job is reflected", function() {
const response = pm.response.json();
pm.expect(response.job).to.eql("Lead SDET");
});
pm.test("updatedAt timestamp is present", function() {
const response = pm.response.json();
pm.expect(response.updatedAt).to.exist;
// Verify it is a recent timestamp (within last minute)
const updated = new Date(response.updatedAt);
const now = new Date();
const diffSeconds = (now - updated) / 1000;
pm.expect(diffSeconds).to.be.below(60);
});// DELETE /api/users/2
pm.test("Delete returns 204", function() {
pm.response.to.have.status(204);
});
pm.test("Response body is empty", function() {
pm.expect(pm.response.text()).to.eql("");
});
pm.test("Response time is under 2 seconds", function() {
pm.expect(pm.response.responseTime).to.be.below(2000);
});// Add this to EVERY request in your collection
pm.test("Response time is under 2 seconds", function() {
pm.expect(pm.response.responseTime).to.be.below(2000);
});
// For the delayed response endpoint (GET /api/users?delay=3)
pm.test("Delayed response takes at least 3 seconds", function() {
pm.expect(pm.response.responseTime).to.be.above(3000);
});
pm.test("Delayed response still returns valid data", function() {
const response = pm.response.json();
pm.expect(response.data).to.be.an("array");
pm.expect(response.data.length).to.be.greaterThan(0);
});Set headers at the collection level so every request gets them automatically. No duplication.
// Set in the collection Pre-request Script tab
pm.request.headers.add({
key: "Content-Type",
value: "application/json"
});
pm.request.headers.add({
key: "Accept",
value: "application/json"
});Put response time checks in a collection-level Test script. That way every request gets the check without you writing it in each request. Collection-level scripts run for ALL requests in the collection.
Do not skip negative test assertions. Checking that a 400 response has the right error message is just as important as checking that a 200 response has the right data. If the API changes its error format, your negative tests catch it.
Q: How do you structure your Postman test assertions?
A: I follow a three-layer approach for every request. Layer 1 is status code validation — the most basic check. Layer 2 is response structure — verifying that expected fields exist and have correct types (string, number, array). Layer 3 is business logic — checking actual values, constraints, and relationships. For negative tests, I verify the error status code, the error message content, and that no sensitive data leaks in error responses. I also add response time checks at the collection level so every request is automatically validated for performance. For chained requests, I save response values to environment variables using pm.environment.set().
Key Point: Every Postman request needs three assertion layers: status code, response structure, and business logic. Add response time checks at the collection level. Negative tests are just as important as positive ones.