Postman Script: Only the Last Request is Getting Executed in a Loop, Why?

54 views Asked by At

why this is happening only request at the last is only getting executed. pre- request script:

const testCases = ['1002', '3002', '100002', 'singh', '1002y'];

    // Set the productid variable for the current iteration
    pm.variables.set('productid', testCases[3]);
    pm.sendRequest({
        url: pm.variables.replaceIn("{{baseUrl}}/products/:productId"),
        method: 'GET'
    });

    pm.variables.set('productid', testCases[0]);
    pm.sendRequest({
        url: pm.variables.replaceIn("{{baseUrl}}/products/:productId"),
        method: 'GET'
    });

test:

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
    if(pm.response.code === 200)
    console.log("ok");
});

pm.test("Status code is 400", function () {
    pm.expect(pm.response.code).to.equal(400);
        if(pm.response.code === 400)
    console.log("Bad Response");
});
console:
 
GET https://valentinos-coffee.herokuapp.com/products/:priductId
400
271 ms
 
GET https://valentinos-coffee.herokuapp.com/products/:priductId
400
275 ms
 
GET https://valentinos-coffee.herokuapp.com/products/1002
200
269 ms
 
ok

In this code also same thing is happening

const testCases = ['1002', '3002', '100002', 'singh', '1002y'];

// Loop through test cases
for (let i = 0; i < testCases.length; i++) {
    // Set the productid variable for the current iteration
    pm.variables.set('productid', testCases[i]);

    // Make the API request
    const response = pm.sendRequest({
        url: pm.variables.replaceIn("{{baseUrl}}/products/:productId"),
        method: 'GET'
    });
}

as you can see from the console only at last the productid is being assigned, tried promise also then only one request is going out, tried adding artificial wait also to make it wait 3 seconds then also same thing is happening only the request at last is having the productid assigned.

i want to rectify it so that for each request there is an output from test then next request goes just like that

3

There are 3 answers

0
Christian Baumann On

Each pm.sendRequest is an asynchronous operation that doesn't block the execution of subsequent code. As a result, when you're looping through your test cases and setting the productid variable, the loop doesn't wait for each request to complete before moving on to the next iteration. This leads to only the last request being executed with the expected productid because the loop has completed its execution and set productid to the last item in your testCases array before any of the requests have had a chance to start.

Moreover, in your pre-request script, there's a typo in the URL parameter name (:priductId should be :productId), which might be contributing to the requests not working as expected.

To rectify the issue and ensure that each request is executed with its corresponding productid, you can use JavaScript's async/await pattern along with Postman's sandbox environment's ability to handle asynchronous operations. Here's how you can modify your loop to wait for each request to finish before proceeding to the next one:

(async () => {
    const testCases = ['1002', '3002', '100002', 'singh', '1002y'];

    for (let i = 0; i < testCases.length; i++) {
        pm.variables.set('productid', testCases[i]);
        
        const url = pm.variables.replaceIn("{{baseUrl}}/products/" + testCases[i]); // Correct the URL substitution
        await new Promise((resolve, reject) => {
            pm.sendRequest(url, {method: 'GET'}, (err, response) => {
                if (err) {
                    console.log(err);
                    reject(err);
                } else {
                    console.log(`Request for productid ${testCases[i]} completed with status ${response.code}`);
                    resolve(response);
                }
            });
        });
    }
})();
0
Bench Vue On

Using Run collection.

It will make it easy to loop API call

enter image description here

Save as 1-demo-collection.json file

{
    "info": {
        "_postman_id": "b0791408-a367-47c1-a96c-3b305a634c10",
        "name": "1-demo",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
        "_exporter_id": "1826150"
    },
    "item": [
        {
            "name": "Get Coffee",
            "event": [
                {
                    "listen": "test",
                    "script": {
                        "exec": [
                            "const jsonData = pm.response.json();",
                            "",
                            "console.log(\"priductIds: \" + pm.collectionVariables.get(\"priductIds\"));",
                            "console.log(\"name: \" + jsonData.name);",
                            "",
                            "let priductIds = JSON.parse(pm.collectionVariables.get(\"priductIds\"));",
                            "if (priductIds.length > 0){",
                            "    postman.setNextRequest(\"Get Coffee\");",
                            "}",
                            "",
                            "pm.test('Status code should be 200 :  ' + pm.response.code, function () {",
                            "    pm.expect(pm.response.code).to.equal(200);",
                            "});",
                            ""
                        ],
                        "type": "text/javascript"
                    }
                },
                {
                    "listen": "prerequest",
                    "script": {
                        "exec": [
                            "let priductIds = JSON.parse(pm.collectionVariables.get(\"priductIds\"));",
                            "console.log(priductIds);",
                            "pm.collectionVariables.set(\"priductId\", priductIds.shift())",
                            "pm.collectionVariables.set(\"priductIds\", JSON.stringify(priductIds));"
                        ],
                        "type": "text/javascript"
                    }
                }
            ],
            "request": {
                "auth": {
                    "type": "noauth"
                },
                "method": "GET",
                "header": [],
                "url": {
                    "raw": "{{baseUrl}}/products/{{priductId}}",
                    "host": [
                        "{{baseUrl}}"
                    ],
                    "path": [
                        "products",
                        "{{priductId}}"
                    ]
                }
            },
            "response": []
        }
    ],
    "event": [
        {
            "listen": "prerequest",
            "script": {
                "type": "text/javascript",
                "exec": [
                    ""
                ]
            }
        },
        {
            "listen": "test",
            "script": {
                "type": "text/javascript",
                "exec": [
                    ""
                ]
            }
        }
    ],
    "variable": [
        {
            "key": "priductIds",
            "value": "[\"1001\", \"1002\", \"1003\", \"1004\", \"3002\"]",
            "type": "string"
        },
        {
            "key": "priductId",
            "value": "1001",
            "type": "string"
        },
        {
            "key": "baseUrl",
            "value": "https://valentinos-coffee.herokuapp.com",
            "type": "string"
        }
    ]
}

Import collection enter image description here

Collection Variable

enter image description here

URL

GET {{baseUrl}}/products/{{priductId}}

Pre-request Script

let priductIds = JSON.parse(pm.collectionVariables.get("priductIds"));
console.log(priductIds);
pm.collectionVariables.set("priductId", priductIds.shift())
pm.collectionVariables.set("priductIds", JSON.stringify(priductIds));

enter image description here

Tests Script

const jsonData = pm.response.json();

console.log("priductIds: " + pm.collectionVariables.get("priductIds"));
console.log("name: " + jsonData.name);

let priductIds = JSON.parse(pm.collectionVariables.get("priductIds"));
if (priductIds.length > 0){
    postman.setNextRequest("Get Coffee");
}

pm.test('Status code should be 200 :  ' + pm.response.code, function () {
    pm.expect(pm.response.code).to.equal(200);
});

enter image description here

Run it enter image description here

Result enter image description here

0
yuvraj singh On

so here's working solution that also maintains the order in which request is going out.

const testCases = ['1002', '3002', '100002', 'singh', '1002y'];

// func to send a request and process the response
function sendRequest(productId, callback) {
    pm.sendRequest({
        url: pm.variables.replaceIn(`{{baseUrl}}/products/${productId}`),
        method: 'GET'
    }, function (err, response) {
        // Tests for the current request after the response is received
        pm.test(`Test for product ID ${productId}`, function () {
            if (response.code === 400) {
                pm.expect(response.code).to.equal(400);
                console.log("Bad Response");
            } else if (response.code === 200) {
                pm.expect(response.code).to.equal(200);
                console.log("ok");
            }
        });

        // Call the callback function to send the next request
            callback();
      });
}

function sendRequestsSequentially(index) {
    if (index < testCases.length) {
        const productId = testCases[index];

        pm.variables.set('productid', productId);

        sendRequest(productId, function() {
            // Send the next request recursively using callback
            sendRequestsSequentially(index + 1);
        });
    }
}

// Start sending requests sequentially
sendRequestsSequentially(0);