Postman API Testing: Writing Test Scripts for REST Endpoints
In this tutorial, you will learn about Postman API Testing: Writing Test Scripts for REST Endpoints. We cover key concepts, practical examples, and best practices to help you master this topic.
Postman provides a built-in test scripting environment using the PM API (pm.test, pm.expect) to validate API responses, assert status codes, check JSON schemas, and run collections programmatically.
What You'll Learn
How to write Postman tests using the PM API, assert response status codes and headers, validate JSON response bodies, check JSON schemas, use Chai assertion syntax, and run tests with the Collection Runner.
Why It Matters
Postman is the most accessible API testing tool with zero setup. Its visual interface and scripting capabilities make it ideal for exploratory testing and quick feedback. DodaTech QA team uses Postman for initial API verification before writing automated framework tests.
Real-World Use
A DodaTech QA engineer opens the User API collection, sends a GET request, and runs 5 test scripts that validate status 200, response format, required fields, data types, and pagination metadata.
flowchart LR
A["Send API\nRequest"] --> B["Pre-request\nScript"]
B --> C["Execute\nRequest"]
C --> D["Tests\nTab Scripts"]
D --> E{"Test\nResults"}
E -->|All Pass| F["Green:\nSuccess"]
E -->|Any Fail| G["Red:\nFailure Details"]
style A fill:#ef7d31,color:#fff
style D fill:#dbeafe,stroke:#2563eb
style F fill:#bbf7d0,stroke:#16a34a
style G fill:#fecaca,stroke:#dc2626
Basic Postman Tests
// Test scripts run after the response is received
// Written in JavaScript using the pm.* API
// 1. Assert status code
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// 2. Assert response body has required fields
pm.test("Response has user data", function () {
const jsonData = pm.response.json();
pm.expect(jsonData).to.have.property("id");
pm.expect(jsonData).to.have.property("email");
pm.expect(jsonData).to.have.property("name");
});
// 3. Assert response time
pm.test("Response time is acceptable", function () {
pm.expect(pm.response.responseTime).to.be.below(500);
});
// Expected test output:
// ✓ Status code is 200
// ✓ Response has user data
// ✓ Response time is acceptable
Advanced Assertions
// 4. Validate array responses
pm.test("Returns array of users", function () {
const jsonData = pm.response.json();
pm.expect(jsonData).to.be.an("array");
pm.expect(jsonData.length).to.be.at.least(1);
jsonData.forEach(user => {
pm.expect(user).to.have.all.keys("id", "email", "name", "created_at");
});
});
// 5. Assert content type header
pm.test("Content-Type is JSON", function () {
pm.response.to.have.header("Content-Type", "application/json");
});
// 6. Assert error response structure
pm.test("Error response has correct format", function () {
const jsonData = pm.response.json();
pm.expect(pm.response.code).to.equal(400);
pm.expect(jsonData).to.have.property("error");
pm.expect(jsonData.error).to.be.a("string");
});
// Expected output:
// ✓ Returns array of users
// ✓ Content-Type is JSON
// (error test only runs on 400 response)
JSON Schema Validation
// 7. Validate response against JSON Schema
const userSchema = {
"type": "object",
"required": ["id", "email", "name", "created_at"],
"properties": {
"id": {"type": "integer"},
"email": {"type": "string", "pattern": "^[\\w.-]+@[\\w.-]+\\.\\w{2,}$"},
"name": {"type": "string", "minLength": 1},
"created_at": {"type": "string", "format": "date-time"}
}
};
pm.test("Response matches user schema", function () {
const jsonData = pm.response.json();
pm.response.to.have.jsonSchema(userSchema);
});
// 8. Test with dynamic data using environment variables
pm.test("Created user has unique ID", function () {
const jsonData = pm.response.json();
// Store for later tests
pm.environment.set("created_user_id", jsonData.id);
pm.environment.set("created_user_email", jsonData.email);
});
// Expected output:
// ✓ Response matches user schema
// ✓ Created user has unique ID
Pre-request Scripts
// Pre-request scripts run BEFORE the request is sent
// 1. Generate dynamic test data
const timestamp = Date.now();
pm.variables.set("unique_email", `test-${timestamp}@example.com`);
pm.variables.set("unique_name", `Test User ${timestamp}`);
// 2. Set authentication token
const token = pm.environment.get("auth_token");
if (token) {
pm.request.headers.add({
key: "Authorization",
value: `Bearer ${token}`
});
}
// 3. Add random data for idempotency
pm.variables.set("idempotency_key",
require('uuid').v4 ? require('uuid').v4() : Math.random().toString(36)
);
// The request body will use {{unique_email}} and {{unique_name}}
// which are resolved at runtime
Running Tests and Using Output
// 9. Test with response headers
pm.test("Rate limit headers present", function () {
pm.response.to.have.header("X-RateLimit-Limit");
pm.response.to.have.header("X-RateLimit-Remaining");
const remaining = parseInt(pm.response.headers.get("X-RateLimit-Remaining"));
pm.expect(remaining).to.be.at.least(0);
});
// 10. Conditional tests
const statusCode = pm.response.code;
if (statusCode === 200) {
pm.test("Successful response data", function () {
const jsonData = pm.response.json();
pm.expect(jsonData.data).to.be.an("array");
});
} else if (statusCode === 404) {
pm.test("Not found message", function () {
pm.expect(pm.response.json().error).to.include("not found");
});
}
// 11. Logging for debugging
console.log("Response time:", pm.response.responseTime + "ms");
console.log("Response body preview:", JSON.stringify(pm.response.json()).slice(0, 200));
Common Mistakes
1. Hardcoding Test Data
Hardcoded emails, IDs, and names cause test failures on re-runs. Use dynamic data with pm.variables.set() and Date.now() or __guid for unique values.
2. Not Testing Error Cases
Most collections only test 200 responses. Always include tests for 400, 401, 403, 404, and 500 responses. Use separate requests in the collection for error cases.
3. Ignoring Response Headers
Headers contain critical information: rate limits, content types, Caching directives, and correlation IDs. Test headers alongside body assertions.
4. Skipping Schema Validation
Status code tests don't catch structural changes. A 200 response with missing fields passes if you only check status. Always validate the response structure with JSON schema.
5. Not Storing Dynamic Values
Tests in the same collection often need values from previous responses (user ID, auth token). Use pm.environment.set() to pass data between requests.
Practice Questions
- What is the difference between pre-request scripts and test scripts?
- How do you pass data between requests in a collection?
- What is JSON schema validation and why use it?
- How do you generate unique test data in Postman?
Answers:
- Pre-request scripts run before the request is sent, used for setup (auth headers, dynamic data). Test scripts run after the response is received, used for assertions and validation.
- Use
pm.environment.set("key", value)in the first request's test script. Usepm.environment.get("key")or{{key}}in subsequent requests. - JSON schema validation checks if the response structure matches a predefined format (field types, required fields, value patterns). It catches structural changes that status code checks miss.
- Use
Date.now()for unique timestamps,pm.variables.set("email", "test-" + Date.now() + "@example.com"), or Postman's built-in{{$guid}}and{{$randomEmail}}dynamic variables.
Challenge: Create a Postman collection for a user management API with 5 endpoints (create, read, update, delete, list). Write tests for each endpoint including success and error cases, use pre-request scripts for dynamic data, pass IDs between requests, validate JSON schemas, and include header assertions.
FAQ
Mini Project
Build a Postman test collection for a Todo API: 6 requests (list, create, get, update, delete, error cases), pre-request scripts for dynamic data, tests for all success/error responses, JSON schema validation for each response, environment variables for API URL and tokens, and collection runner verification.
What's Next
Postman Collections — organize and manage test collections.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro