Postman Scripts: Advanced Pre-request and Test Scripting Techniques
In this tutorial, you will learn about Postman Scripts: Advanced Pre. We cover key concepts, practical examples, and best practices to help you master this topic.
Postman scripting extends beyond basic assertions with request chaining, cryptographic functions, date manipulation, XML parsing, external library usage, and reusable snippet libraries for complex test scenarios.
What You'll Learn
Advanced Postman scripting techniques: chaining requests with pm.sendRequest, using CryptoJS for signatures, moment.js for date manipulation, XML2JS for XML APIs, building reusable snippet libraries, and debugging complex scripts.
Why It Matters
Complex API testing scenarios require cryptographic signing, OAuth flows, multi-step request chains, and data transformation. Postman's sandboxed JavaScript runtime supports these natively. DodaTech uses advanced scripts for HMAC-signed Webhook testing and OAuth token refresh chains.
Real-World Use
A DodaTech webhook test needs an HMAC-SHA256 signature in the header. The pre-request script generates the signature using CryptoJS, adds it to headers, and the test script validates the 200 response and signature verification.
flowchart LR
A["Pre-request\nScript"] --> B["Generate\nHMAC Signature"]
B --> C["Add Signature\nHeader"]
C --> D["Send\nRequest"]
D --> E["Test Script\nRuns"]
E --> F["Verify Status\nand Signature"]
style A fill:#dbeafe,stroke:#2563eb
style B fill:#fef3c7,stroke:#d97706
style F fill:#bbf7d0,stroke:#16a34a
Chaining Requests
// pm.sendRequest - send additional requests from scripts
// Test: Create user, then verify it exists
pm.test("Create and verify user", function () {
const newUser = {
email: `user-${Date.now()}@test.com`,
name: "Test User",
password: "SecurePass123!"
};
const createRequest = {
url: pm.collectionVariables.get("base_url") + "/users",
method: "POST",
header: {
"Content-Type": "application/json",
"Authorization": `Bearer ${pm.environment.get("auth_token")}`
},
body: {
mode: "raw",
raw: JSON.stringify(newUser)
}
};
pm.sendRequest(createRequest, function (err, response) {
if (err) {
console.error("Create failed:", err);
return;
}
pm.expect(response.code).to.equal(201);
const userId = response.json().id;
// Now verify the user exists
const getRequest = {
url: `${pm.collectionVariables.get("base_url")}/users/${userId}`,
method: "GET",
header: {
"Authorization": `Bearer ${pm.environment.get("auth_token")}`
}
};
pm.sendRequest(getRequest, function (err2, response2) {
pm.expect(response2.code).to.equal(200);
pm.expect(response2.json().email).to.equal(newUser.email);
console.log(`User ${userId} created and verified`);
});
});
});
HMAC Signing and CryptoJS
// Pre-request: Generate HMAC-SHA256 signature for webhook testing
const timestamp = Math.floor(Date.now() / 1000).toString();
const payload = pm.request.body.raw || "";
const secret = pm.environment.get("webhook_secret");
// Generate signature using CryptoJS (built-in)
const signature = CryptoJS.HmacSHA256(
timestamp + "." + payload,
secret
).toString(CryptoJS.enc.Hex);
// Add signature headers
pm.request.headers.add({
key: "X-Webhook-Signature",
value: signature
});
pm.request.headers.add({
key: "X-Webhook-Timestamp",
value: timestamp
});
console.log(`Signature: ${signature.slice(0, 20)}...`);
console.log(`Timestamp: ${timestamp}`);
Date Manipulation with Moment.js
// Moment.js is built into Postman sandbox
// Pre-request: Generate date ranges for query params
const now = moment();
const startDate = now.format("YYYY-MM-DD");
const endDate = now.add(30, "days").format("YYYY-MM-DD");
pm.variables.set("start_date", startDate);
pm.variables.set("end_date", endDate);
// Generate timestamps for rate-limiting tests
const oneHourAgo = moment().subtract(1, "hour").unix();
const oneHourLater = moment().add(1, "hour").unix();
console.log(`Query range: ${startDate} to ${endDate}`);
// Test script: validate date format in response
pm.test("Response date is valid ISO format", function () {
const jsonData = pm.response.json();
if (jsonData.created_at) {
const valid = moment(jsonData.created_at, moment.ISO_8601, true).isValid();
pm.expect(valid).to.be.true;
}
});
XML Parsing
// xml2js is built into Postman for XML API testing
// Test: Parse XML response and validate
pm.test("XML response has correct structure", function () {
const xmlData = pm.response.text();
const parser = new xml2js.Parser({ explicitArray: false });
parser.parseString(xmlData, function (err, result) {
if (err) {
console.error("XML parse error:", err);
pm.expect.fail("Invalid XML response");
return;
}
// Navigate parsed XML object
const root = result.response || result.root;
pm.expect(root).to.have.property("status");
pm.expect(root.status).to.equal("success");
if (root.data) {
const items = Array.isArray(root.data.item)
? root.data.item
: [root.data.item];
pm.expect(items.length).to.be.at.least(1);
pm.expect(items[0]).to.have.property("id");
console.log(`XML parsed: ${items.length} items found`);
}
});
});
Reusable Snippet Library
// Pre-request scripts can include reused logic via functions
// Define reusable functions in collection-level pre-request
const TestUtils = {
// Generate unique test email
uniqueEmail: function (prefix) {
return `${prefix || "test"}-${Date.now()}@example.com`;
},
// Create auth header
authHeader: function () {
return `Bearer ${pm.environment.get("auth_token")}`;
},
// Wait for async processing
waitForStatus: function (checkUrl, targetStatus, maxRetries, callback) {
let attempts = 0;
const check = function () {
attempts++;
pm.sendRequest({
url: checkUrl,
method: "GET",
header: { "Authorization": TestUtils.authHeader() }
}, function (err, response) {
if (err) {
callback(err);
return;
}
const status = response.json().status;
if (status === targetStatus || attempts >= maxRetries) {
callback(null, response);
} else {
setTimeout(check, 1000);
}
});
};
check();
}
};
// Usage in individual test:
const email = TestUtils.uniqueEmail("user");
pm.variables.set("user_email", email);
console.log(`Generated email: ${email}`);
Common Mistakes
1. Not Handling pm.sendRequest Callbacks
pm.sendRequest is asynchronous. If you don't put assertions inside the callback, they run before the response arrives. Always nest assertions within the callback function.
2. Overlooking the Sandbox Limitations
Postman sandbox does not support Node.js built-in modules (fs, path, http), browser APIs (fetch, DOM), or npm packages. Use built-in libraries (CryptoJS, moment, xml2js) instead.
3. Infinite Loops with Retries
When polling for async status, always set a max retry limit and timeout. Without limits, a stuck Process runs indefinitely and the collection runner never completes.
4. Not Cleaning Up Test Data
Test scripts that create resources should also delete them. Use pm.sendRequest in the test script to clean up after yourself, especially in CI runs where state persists.
5. Sharing State Across Async Calls
Variables set inside a pm.sendRequest callback may not be available to the next test if the collection runner continues before the callback fires. Use synchronous patterns or the Postman Runner's iteration flow.
Practice Questions
- How do you send additional HTTP requests from within a test script?
- What built-in cryptographic libraries does Postman provide?
- How do you parse XML responses in Postman?
- What are the limitations of the Postman script sandbox?
Answers:
- Use
pm.sendRequest(requestObject, callbackFunction). The callback receives(error, response)when the request completes. All assertions must be inside the callback. CryptoJSis built-in for HMAC, SHA, MD5, AES, and other crypto operations. Also available:CryptoJS.enc.Hex,CryptoJS.enc.Base64, andCryptoJS.enc.Utf8.- Use the built-in
xml2jslibrary. Create a parser withnew xml2js.Parser(), callparser.parseString(xmlText, callback), and navigate the resulting JavaScript object. - No filesystem access (fs), no raw networking (net/http), no DOM APIs, no npm module installation (only built-in libraries). Use environment variables instead of file storage.
Challenge: Build a complex test flow: create an order via API, generate HMAC signature for webhook simulation, poll for async status changes with retry logic, validate XML response from a legacy endpoint, clean up created resources, and log all steps to the Postman Console.
FAQ
Mini Project
Build an advanced Postman script collection: create a test suite with HMAC-signed webhook verification, async polling with retry logic, XML response parsing, date-range query parameters, chained create-verify-delete flow, rate limit handling, and a reusable utility library. Run with Newman in CI.
What's Next
Newman CLI — run Postman collections from the command line and CI.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro