The Postman forums have quite a few topics dedicated to the async nature of sendRequest().
I’m trying to produce a clean example on how this works with reusable code.
I’ve run into some queries around calling the async function within a loop.
The following code show the issue with the async nature of sendRequest().
for (let i = 1; i < 11; i++) {
let testValue = `request${i}`
let request = {
url: 'https://postman-echo.com/get?test=' + testValue,
method: 'GET',
}
pm.sendRequest(request, (err, res) => {
if (err) {
console.log(err);
}
pm.test(`Request ${i} - status code is 200`, () => {
pm.expect(res).to.have.status(200);
let resJson = res.json();
console.log(resJson.args.test);
});
});
};
The requests are unordered, as shown in the console logs.
Using promises and awaits resolves the main issue.
const sendRequest = (req) => {
return new Promise((resolve, reject) => {
pm.sendRequest(req, (err, res) => {
if (err) {
console.log(err);
return reject(err);
}
resolve(res);
});
});
};
(async () => {
for (let i = 1; i < 11; i++) {
let testValue = `request${i}`
let request = {
url: 'https://postman-echo.com/get?test=' + testValue,
method: 'GET',
}
const response = await sendRequest(request); // wait for promise to be resolved before continuing
pm.test(`Request ${i} - status code is 200`, () => {
pm.expect(response).to.have.status(200);
let resJson = response.json();
console.log(resJson.args.test);
});
}
})();
With the requests now in the correct order.
I wanted to make the async function a bit more re-usable and tried to put the loop outside of the function.
const sendRequest = (req) => {
return new Promise((resolve, reject) => {
pm.sendRequest(req, (err, res) => {
if (err) {
console.log(err);
return reject(err);
}
resolve(res);
});
});
};
async function asyncCall(request) {
const response = await sendRequest(request);
pm.test(`Request ${i} - status code is 200`, () => {
pm.expect(response).to.have.status(200);
let resJson = response.json();
console.log(resJson.args.test);
});
};
for (let i = 1; i < 11; i++) {
let request = {
url: 'https://postman-echo.com/get?test=' + `request${i}`,
method: 'GET',
}
asyncCall(request);
};
This sends the requests, but they are no longer in order.
The tests aren’t running either.
What am I doing wrong with this approach.
2
Answers
The variable
i
is declared inside the for loop, and it is not accessible inside thepm.test
function. This will result in an undefined value fori
in the test name.Here is my proposed code:
The latest version of the Postman App supports top-level await, and
pm.sendRequest
returns a promise.So now you can directly do this: