1

Update I've completely rewritten this question based on subsequent investigation. Hopefully this will generate some answers.

I'm new to Postman, and trying to figure out how to most efficiently build a collection of tests for a REST application. There are a bunch of utility functions that I'd like to have accessible in each of my test scripts, but cut-and-paste-ing them in to each test script seems like a horrible solution.

In looking at the various "scopes" that Postman allows you to squirrel away data (e.g. globals, environment, collection), it seems that all of these are merely string/number stores. In other words, it properly stores them if you can/do stringify the results. But it doesn't actually allow you to store proper objects or functions. This makes sense, since each script seems to be run as a separate execution, so the idea of sharing pointers to things between different scripts doesn't make sense.

It seems like the accepted way to share utility functions is to toString() the function in the defining script (e.g. the Collection Pre-Req script), and then eval() that stringified version in the test script. For instance:

Collection Pre-Req Script

const utilFunc =  () => { console.log("I am a utility function"); };
pm.environment.set("utilFunc",utilFunc.toString() );

Test Script

const utilFunc = eval(pm.environment.get("utilFunc"));
utilFunc();

The test script will successfully print to console "I am a utility function".

I've seen people do more complicated things where, if they have more than one utility function, put them in to an object like utils.func1 and utils.func2, and have the overall function return the utils object, so the test script still only has to have a single line at the top importing the whole thing.

The problem I'm running in to is scoping - since the literal text of the function is executed in the Test Script, everything thing that the utility function has to have must be in that code, or otherwise exist at eval() time in the Test Script. For instance, if I do:

Collection Pre-Req Script

const baseUtilFunc = (foo) => { console.log(foo); };

const utilFunc1 = (param) => { baseUtilFunc("One: " + param); };
const utilFunc2 = (param) => { baseUtilFunc("Two: " + param); };

pm.environment.set("utilFunc1",utilFunc1.toString() );
pm.environment.set("utilFunc2",utilFunc2.toString() );

Test Script

const utilFunc1 = eval(pm.environment.get("utilFunc1"));
const utilFunc2 = eval(pm.environment.get("utilFunc2"));
utilFunc1("Test");

This fails because, in the Test Script, baseUtilFunc does not exist. Obviously, in this example, it'd be easy to fix. But in a more complicated world where the utility functions I expect to use in my Test Scripts are themselves built on top of underlying helper functions, it gets more difficult.

So what is the right way to handle this issue? Do people just cram all the relevant logic in to one big function that they then call toString() on? Do they embed an extraction-from-environment-and-then-eval in each util function within its definition, so that it works in the Test Script context? Do they export each individual method?

Doug
  • 644
  • 1
  • 6
  • 22
  • See https://stackoverflow.com/questions/45673961/how-to-write-global-functions-in-postman – Ori Marko May 10 '18 at 09:00
  • That seems to give you information on the basics of accessing shared functions between scripts. but it doesn't address the more complicated question of how to manage shared scripts that refer to other functions/objects/etc. - who, in a simple coding model, won't be availale in the eval() scope. – Doug May 10 '18 at 09:15

1 Answers1

2

There are different ways to do it. The way I did recently for one of the projects is creating a project in Git and then using raw url to fetch the data. I have a sample created at below repo

https://github.com/tarunlalwani/postman-utils

To load the file you will need to associate the below code at collection level

if (typeof pmutil == "undefined") {
    var url = "https://raw.githubusercontent.com/tarunlalwani/postman-utils/master/pmutils.js";

    if (pm.globals.has("pmutiljs"))
        eval(pm.globals.get("pmutiljs"))
    else {
        console.log("pmutil not found. loading from " + url);
        pm.sendRequest(url, function (err, res) {
            eval(res.text());
            pm.globals.set('pmutiljs', res.text())
        });
    }
}

As shown in below screenshot

Collection Pre-Request

And the later in the tests or Pre-Requests you will run the below line of code to load it

eval(pm.globals.get("pmutiljs"))

And then you can use the functions easily in test.

Tests with reusable functions

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265