Postman - how to request a loop until I get a specific response?
I'm testing an API with Postman and I have a problem: My request is middleware, so I either get a full 1000+ JSON string, or I get a status PENDING
and an empty array of results:
{
"meta": {
"status": "PENDING",
"missing_connectors_count": 0,
"xxx_type": "INTERNATIONAL"
},
"results": []
}
The question is, how do I loop this query in Postman until I get the status SUCCESS
and results array > 0
? When I submit these requests manually one at a time, this is fine, but when I run them through the Collection Runner, "PENDING" messes things up.
source to share
Try it:
var body = JSON.parse(responseBody);
if (body.meta.status !== "SUCCESS" && body.results.length === 0){
postman.setNextRequest("This_same_request_title");
} else {
postman.setNextRequest("Next_request_title");
/* you can also try postman.setNextRequest(null); */
}
source to share
When waiting for services to be ready or when polling the results of a long-term job, I see four main options:
- Use Postman collection explorer or new user and set the delay in a step. This delay is inserted between each step of the collection. There are two problems here: it can be fragile if you don't set the delay to a value that will never exceed its duration; And often this delay requires only a small number of steps, and you increase the overall test execution time by creating excessive build times for the shared build server to delay other pending builds.
- Use
https://postman-echo.com/delay/10
where the last URI element takes a few seconds. It's simple and concise and can be inserted as one step after a long query. The challenge is that the request duration varies a lot, you can get false failures because you haven't waited too long. - Repeat this step until you succeed with
postman.setNextRequest(request.name);
. The challenge here is that the postman will execute the request as fast as he can, which can DDoS your service, get blacklisted (and cause false crashes), and chew on a lot of CPUs if they run on a shared build server - slowing down others builds. - Use setTimeout () in pre-request Script . The only drawback I see with this approach is that if you have multiple steps that require this logic, you end up with cut and paste code that needs to be synchronized
Note : there are slight variations on these - for example setting them in a collection, collection folder, step, etc.
I like option 4 because it provides the right level of detail for most of my use cases. Note that this is the only way to "sleep" in the Postman script. Now standard javascript techniques like Promise with async and await are not supported, and using the lodash sandbox _.delay(function() {}, delay, args[...])
does not support script execution on a pre-request script.
In Postman v6.0.10 standalone app, set the Pre-request script step to:
console.log('Waiting for job completion in step "' + request.name + '"');
// Construct our request URL from environment variables
var url = request['url'].replace('{{host}}', postman.getEnvironmentVariable('host'));
var retryDelay = 1000;
var retryLimit = 3;
function isProcessingComplete(retryCount) {
pm.sendRequest(url, function (err, response) {
if(err) {
// hmmm. Should I keep trying or fail this run? Just log it for now.
console.log(err);
} else {
// I could also check for response.json().results.length > 0, but that
// would omit SUCCESS with empty results which may be valid
if(response.json().meta.status !== 'SUCCESS') {
if (retryCount < retryLimit) {
console.log('Job is still PENDING. Retrying in ' + retryDelay + 'ms');
setTimeout(function() {
isProcessingComplete(++retryCount);
}, retryDelay);
} else {
console.log('Retry limit reached, giving up.');
postman.setNextRequest(null);
}
}
}
});
}
isProcessingComplete(1);
And you can run your standard tests in the same step.
Note . Standard caveats apply to making the retryLimit large.
source to share
I was looking for an answer to the same question and was thinking about a possible solution as I read your question. Use the postman workflow to rerun your request every time you don't get the answer you're looking for. Anyway, this is what I will try.
postman.setNextRequest("request_name");
source to share