Search code examples
javascripttestingpostmanpostman-pre-request-script

Pre-request script doesn't change the collection variable using Postman


Pre-Request Script:

let user_id = pm.collectionVariables.get("user_id");
pm.sendRequest(`http://security.postman-breakable.com/account/${user_id}/summary`, function (err, response) {
    if(response.status == "FORBIDDEN"){
        pm.collectionVariables.set("status_code", 403);
    }else if(response.status == "OK"){
        pm.collectionVariables.set("status_code",200);
    }
});

Test:

let status_code = parseInt(pm.collectionVariables.get("status_code"));
pm.test(`Status code is ${status_code}`, function () {
    pm.response.to.have.status(status_code);
});

The response code is 200 but it reads the previous response code which was 403.

Although I try to change my collection variable called "status_code" by writing pre-request script when the response code changes, it doesn't change.


Solution

  • I can replicate this 100% of the time. Searching for a solution brought me here.

    I truly think it's a bug: it seems that Pre-request Scripts (in 10.8.7) get either a shallow copy of whatever state Collection Variables were in at time of Send, or the binding between pm.collectionVariables and Collection Variables has broken. I can't imagine that this behavior is intentional.

    For now, I would suggest that you refactor this into a Request and have code in a Test do the pm.collectionVariables.set()

    The following doesn't apply to your specific use case, but perhaps it will be relevant to whomever finds this question before the bug is fixed: for my own use I built a utility object with a function to manipulate a "cleanup" list in Collection Variables, but changes wouldn't persist. The workaround for my case is to pass the pm.collectionVariables reference from the Test sandbox at call-time, since that instance seems bound to Collection Variables in the UI.

    My Collection's Pre-request Script:

    utils = {
        addCleanup: (collection, route, id) => {
            const list = JSON.parse(collection.get('test_cleanup_list'));
            list.push({ route, id, id_field: `${route}id`});
            collection.set('test_cleanup_list', JSON.stringify(list));
            return list;
        }
    };
    

    and then from a Test in a Request later in the Run:

    utils.addCleanup(pm.collectionVariables, 'account', account.id);