How to encapsulate multiple pm.sendRequest()'s in a single test?

I need to verify the response of a request. In the past, I could simply make a test with a forEach loop over the data (as it is an array, and I need to check every entry). However, recently the way the requests are handled has changed, and now I need to make an additional request for each item in the array to get at the data which I need to verify.

I’ve decided that I want to use the pm.sendRequest() method for this, and initially tried just moving the pm.expect()'s into the request’s callback, but that caused errors instead of simply failing the test. I then tried putting the entire test into the callback, but that created several hundred extra tests, which I shouldn’t have to explain is not good either.

I’m having trouble getting it to work, and was wondering if anyone knows if it is even possible to have multiple requests only go back to a single test? I don’t mind that pm.sendRequest() is asynchronous (order is not important), but I would like to only have to deal with 1 test, not several hundred.

Theoretical response from initial request:

[
  '8n9w4avb87sk',
  '903v4t934fds',
  '08vrhn2v3rh9',
  'vt6429mi24vi'
]

Theoretical response of one of the pm.sendRequest()'s:

{
  'name': 'John Doe',
  'roles': [
    'ADMIN',
    'USER'
  ],
  'lastLogin': '2022-09-28'
}

Can I just check your logic.

You are sending an initial request…
and using the response to that request…
you want to loop through the array…
and send another request and verify some element…
but you want to wrap it in a single test? (the whole array must pass?)

If I remember rightly, you can write directly to the test results outside of a traditional test function. I’d have to find the post to see the format. You can write a pass or fail with custom text. Therefore it sounds like you should be able to loop through your array, and if one fails, write a fail to the results and exit the loop. Otherwise, if the whole loop is processed without an error, you can write a pass to the results.

Have a look at the following which shows an example of writing directly to the results.

I’m sorry, but I couldn’t find any usable code that applies to my issue. It seems that the person you linked to only needed help debugging their custom test messages, not with testing results of asynchronous calls.

I was able to finally bend Postman to my will using this method:

const jsonData = pm.response.json();
var reqs = new Array(jsonData.length);

for(var i = 0; i < testers.length; i ++) {
  var item = jsonData[i];
  testers[i] = new Promise((resolve, reject) => {
    pm.sendRequest("https://some.website/" + item, (err, resp) => {
      let ret = "some value(s) we want to test against";
      // Whatever else we need to process
      resolve(ret);
    });
  });
}

async function testHere() {
  for(let i = 0; i < reqs.length; i++) {
    reqs[i] = await reqs[i];
  }
  pm.test("This is a test", () => {
    reqs.forEach((item) => {
      // Your normal testing goes here
    });
  });
}

testHere();

Addendum:
If you are setting postman variables in either the async function or the promises, be sure to include setTimeout(() => {}, 1000); at the end of the script, so that the program waits a bit longer in case it is taking a bit too long to send all the requests and test the results, especially if you run this in a collection, or else the variables will not be set. I’ve found that 1 second timeout (1000 ms) for every 100 sendRequest()s or so provides sufficient delay.