skip to Main Content

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.

enter image description here

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.

enter image description here

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.

enter image description here

The tests aren’t running either.

What am I doing wrong with this approach.

2

Answers


  1. The variable i is declared inside the for loop, and it is not accessible inside the pm.test function. This will result in an undefined value for i in the test name.

    Here is my proposed code:

     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, i) {
        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, i);
    };
    
    Login or Signup to reply.
  2. The latest version of the Postman App supports top-level await, and pm.sendRequest returns a promise.
    So now you can directly do this:

    for (let i = 0; i < 10; i++) {
        const response = await pm.sendRequest(`https://postman-echo.com/get?test=request${i}`);
    
        pm.test(`Request ${i} - status code is 200`, () => {
            pm.expect(response).to.have.status(200);
            
            let resJson = response.json();
            console.log(resJson.args.test);
        });
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search