Postman Exploration
Before you automate, understand the API. Postman is the universal tool for manual API exploration — it lets you send requests, inspect responses, chain calls together, and build a mental model of how the API behaves before writing a single line of test code.
Getting Started with Postman
1. Import the API Spec
Most APIs provide an OpenAPI (Swagger) specification. Importing it into Postman auto-generates a collection with every endpoint, request body schema, and example parameters.
File > Import > OpenAPI/Swagger URL or file
This gives you an instant starting point: every endpoint is documented with expected parameters and response schemas.
2. Set Up Environments
Environments hold variables that switch between dev/staging/production without modifying requests.
| Variable | Dev | Staging | Production |
|---|---|---|---|
{{base_url}} |
http://localhost:3000 |
https://api.staging.example.com |
https://api.example.com |
{{auth_token}} |
(dev token) | (staging token) | (read-only prod token) |
{{timeout}} |
5000 | 10000 | 10000 |
Switch environments with the dropdown in the top-right corner. All requests using {{base_url}} automatically point to the correct server.
3. Organize Collections
Structure collections to mirror the API structure:
My API Collection/
Auth/
POST Login
POST Refresh Token
POST Logout
Users/
GET List Users
GET Get User by ID
POST Create User
PUT Update User
DELETE Delete User
Orders/
GET List Orders
POST Create Order
GET Get Order by ID
Writing Test Scripts
Postman's test scripts run after each request, validating responses inline.
Basic Assertions
// Status code
pm.test("Status is 200", () => {
pm.response.to.have.status(200);
});
// Response has expected fields
pm.test("Response has user ID", () => {
const data = pm.response.json();
pm.expect(data.id).to.be.a("number");
pm.expect(data.email).to.be.a("string");
pm.expect(data).to.not.have.property("password");
});
// Response time
pm.test("Response time < 500ms", () => {
pm.expect(pm.response.responseTime).to.be.below(500);
});
// Headers
pm.test("Content-Type is JSON", () => {
pm.response.to.have.header("Content-Type", "application/json; charset=utf-8");
});
Chaining Requests
Extract data from one request and use it in the next:
// In POST /auth/login Tests tab:
pm.test("Save auth token", () => {
const token = pm.response.json().access_token;
pm.environment.set("auth_token", token);
});
// In subsequent requests, use {{auth_token}} in the Authorization header:
// Bearer {{auth_token}}
Dynamic Variables
Postman provides built-in dynamic variables:
{{$randomEmail}} -> random email address
{{$randomFullName}} -> random name
{{$randomUUID}} -> UUID v4
{{$timestamp}} -> current Unix timestamp
{{$randomInt}} -> random integer
Pre-Request Scripts
Pre-request scripts run before the request is sent — useful for generating dynamic data or calculating signatures.
// Generate a unique email for each test run
const timestamp = Date.now();
pm.environment.set("test_email", `testuser_${timestamp}@test.com`);
// Calculate HMAC signature for signed requests
const CryptoJS = require('crypto-js');
const secret = pm.environment.get("api_secret");
const payload = JSON.stringify(pm.request.body.raw);
const signature = CryptoJS.HmacSHA256(payload, secret).toString();
pm.request.headers.add({ key: "X-Signature", value: signature });
Collection Runner
The Collection Runner executes all requests in a collection sequentially, with test assertions.
Running a Collection
- Click "Runner" in Postman
- Select the collection
- Choose the environment
- Set iterations (run the entire collection N times)
- Upload a data file for data-driven testing
Data-Driven Testing
Create a CSV or JSON file with test data:
email,password,expected_status
valid@test.com,ValidPass123!,200
invalid@test.com,wrong,401
,ValidPass123!,400
valid@test.com,,400
In the request body, reference columns: {{email}}, {{password}}
In the test script:
pm.test(`Login with ${pm.iterationData.get("email")} returns ${pm.iterationData.get("expected_status")}`, () => {
pm.response.to.have.status(parseInt(pm.iterationData.get("expected_status")));
});
Postman Monitors and Workspaces
Monitors
Schedule collections to run automatically (e.g., every hour) and receive alerts when tests fail. Useful for production health checks.
Workspaces
Share collections across team members. Changes sync automatically. Use workspaces for team API documentation and shared test collections.
Postman Limitations
| Limitation | Impact | Alternative |
|---|---|---|
| Not ideal for CI/CD | Requires Newman for command-line execution | Use Newman or pytest directly |
| Collections become unwieldy at scale | Hard to manage 500+ requests | Use code-based tests (pytest) |
| Limited programming model | JavaScript only, limited libraries | Full language ecosystem in pytest/Jest |
| Version control | JSON export is hard to diff | Code-based tests in Git |
| Complex assertions | Difficult to build reusable assertion libraries | Python/TypeScript assertion libraries |
Postman excels at exploration and prototyping. For production CI/CD pipelines, transition to code-based automation.
Practical Exercise
- Find a public API with an OpenAPI spec (e.g., Petstore, JSONPlaceholder, or your company's API)
- Import the spec into Postman
- Create staging and production environments
- Write test scripts for at least 5 endpoints: verify status codes, response structure, and absence of sensitive data
- Chain a login request with a protected endpoint using environment variables
- Run the collection with the Collection Runner and review the results
Key Takeaways
- Use Postman for API exploration before writing automated tests
- Set up environments to switch between dev/staging/production easily
- Write test scripts to validate responses inline
- Chain requests using environment variables (save token from login, use in subsequent requests)
- Use the Collection Runner for batch execution and data-driven testing
- Transition to code-based automation (pytest, Newman) for CI/CD