Conditional Workflows in Postman
This is the first in a 3 part series on non-linear workflows using Postman.
There are some products available in the market to create and execute API workflows. However, most of them are limited by their linear, non-reactive execution. We knew we could create something much more effective and decided to add workflow support to Postman. Postman 4.0, in conjunction with Newman, the command line companion, is now powerful enough to help you create and execute non-linear workflows in your Collections!
This latest release builds upon our existing Collection Runner. It introduces a new function called postman.setNextRequest. As is evident from the name, you just need to specify the name of the subsequent request and the runner will take care of the rest. It has the following signature:
postman.setNextRequest(βRequest Nameβ);
while
postman.setNextRequest(null);
terminates execution.
Below we will go over an example workflow so you can get a sense of how this works.
You might have met Postmanβs Chief Happiness Officer earlier.
This is Cooper. Heβs one year old and eats three meals a day. Heβs allowed to eat only six pre-approved food items. We store them in a database. Cooper is very picky. You canβt repeat an item on the same day unless you want to risk a tantrum. So I want to generate a random meal plan for him at the beginning of the week.
The workflow:
First makes the API call to GET the list of approved food for Cooper from the database.
Then it creates an entry for each day, 3 times a day, 7 days a week
All 3 meals in a single day have to be unique.
If the API call fails, poor Cooper goes hungry π
In case you’re curious, I ran the collection and hereβs what Cooperβs eating this week!
In general, the postman.setNextRequest parameter is associated with the request and can be set in the pre-request or the test script. In case of more than one assignment, the last set value is considered. If postman.setNextRequest is absent, the runner defaults to the linear execution and moves to the next request.
I hope you find this useful. postman.setNextRequest is just the beginning and we will push out more APIs to easily create complex workflows in the coming quarters within Postman. Stay tuned!
Update: Part 2 and 3 of non-linear workflows using Postman
Part 2: Generate Spotify Playlists using a Postman Collection
Part 3: “Daily Mix” with Postman Monitors and Spotify
Postman allows same name for multiple workflows. In this case which workflow will be picked up?
The first request is chosen right now. e.g. A->B->C->B is how the requests are arranged in the collection. If C has a setNextRequest to B, the first B (A->B) will be chosen.
However, I wouldn’t recommend relying on this. Next month, we’ll add friendly IDs to the UI, so you can view and choose the friendly ID, rather than the potentially confusing use of name.
e.g. in the collection in the article, if there were 2 requests with the same name “Create Day Log”, they would be probably be named create-day-log and create-day-log-2
In case if cyclic calls are made (with no conditions resulting to infinite loop), postman runner hangs. Is there’s any provision for avoiding the scenario?
Currently the flow control is completely in the user’s hand, but we will add features to avoid and debug infinite loops very soon.
Amazing job. Kudos to the postman team. π
Thanks. We are really excited about this! Will have an even more exciting follow up post very soon
Really nice work π It is so much helpful! Thanks!!
This is a great function, and a huge boon to those of us who are looking to work smarter not harder – I have one small suggestion regarding it, however.
It would be fantastic if there was functionality in the Pre-request Script to skip the current call and move directly to the next step in the line. Being able to specify where the runner goes helps, but being able to choose whether it goes there before or after the current call is triggered would be huge.
My specific context for this ask is this: I have a collection I am running to test out our API. It takes a significant amount of time, and thus the token expires about halfway through the process. I would like to add the token call into the collection, but the server gets rather irritated when I request one token after another, so I would like to add a check against the expiration date of the current token in the pre-request script of the token call. That way if it’s expired, I will retrieve a new one, otherwise I will skip the current step and move forward to the next portion.
Anyhow, great job on the new functionality – it’s already adding so much to an incredible application.
Nathan, thanks for the feedback. Really appreciate it π
I consider the combination of pre-request, the actual request and test script to be a single entity. Breaking them up and allowing the skip of the request section would, I think, lead to more confusion than control.
That said, I would approach your problem by testing for the token expiry in the test script of the previous request. If it were to fail, setNextRequest to “Refresh Token” and store the name of the intended next request in the environment variable.
Let’s say 2 requests A and B and the workflow:
Get Access Token -> A -> B
Now, before B were to execute, the token expired.
Get Access Token -> A -> Refresh Token -> B
in the test script of A, assuming tokenExpired() is a function to check expiry
if (tokenExpired()) {
postman.setEnvironmentVariable(“nextRequest”, “B”);
postman.setNextRequest(“Refresh Token”);
}
else {
postman.setNextRequest(“B”);
}
And in the test script section of Refresh Token:
if (environment.nextRequest) {
postman.setNextRequest(environment.nextRequest);
}
Let me know if this helps!
@ankitsobti:disqus your solution does not work when you execute the first request of a collection and the token is expired and does not work also when you want to execute a single request(without a previous one).
I think a better solution is:
General idea:
Execute request X, if the token is invalid execute “Refresh Token” request and then execute the request X again.
X -> Refresh Token -> X
Specified Idea:
In the Tests section(should be named Post-request section) of request X, to check the response of the request and if the response say that the token is invalid( 401 code for example) then:
1- Set a GlobalEnvironment variable when the name of the current request.
Example: postman.setEnvironmentVariable(“Request4ComeBack”, “X”);
2- Call the “Refresh Token” request and to check in the Tests section of this one if the var Request4ComeBack have some value, if it has then:
1- postman.setNextRequest(environment.Request4ComeBack);
2- clear the Request4ComeBack var.
This is exactly what I came here looking for. There needs to be, I think, two possible options within the Pre-Request script
1. Skip this test, w/o running the web call. Like don’t try to close a workflow task because it’s not open (based on environment variables you’ve set in a previous test), and that’s okay. Not a failure. Just not applicable.
2. Fail this test (also w/o running the web call) because you can’t close the workflow task because it wasn’t opened and that’s NOT okay.
(By workflow, I mean our tasking API we’re testing, not the Postman workflow.)
In the above scenarios, testing flow would just continue to the next test in line.
The ability to change the target of the next test is a great idea and I’ll try to find a way to use it, but it eliminates the ability to re-use a given task’s Pre-Request Script and Tests code again because it’s very tied to the testing suite it’s in.
how do I run a request thats prerequisite for multiple reuqests in a prerequest script?
Toye, check out my answer to Nathan below and see if it helps. Or elaborate your scenario a little further, and I’ll help you out.
Lets say I have request A that returns a value. And i have 5 different requests that need said value. I want to be able to execute A before any of those requests with A defined only once.
Hi,
Do you have any plans for generating reports of test runs may be in csv or excel sheet?
Not yet, but I’ll keep you posted if we do add it at some point
Wonderful. Ask you one question. Where to find the all postman API? Such as postman.setNextRequest, postman.setGlobalVariable. I think if we get all these API, we may have more option to organize our cases. π
You can check out the documentation here: https://www.postman.com/docs/testing_examples
Thank you. The wiki page contains the basic Postman API. But it’s partial, not all list of Postman API, such as postman.setNextRequest, not including in it. Where can we get all the list of Postman API? In order to enhance and organize our cases.
@ankitsobti:disqus , one more question. Is there a way to include one common collection in the other collection? For example, the Login collection can be a common collection as the pre-request for other test, we can refer the path of common collection in the re-request. So if Login case update, we need only to update one collection, and no need to update it in every collection. Thanks.
@Ankit Sobti ,I have the same question.I need one common collection for calling before othen requests in my project.Is there any better solution? Thanks.
Nice feature, but when you have a request that must be executed each time after another request you have to put this request duplicated after each another request.
Anyhow really nice work, was the 10$ better spent π
I have a question: Will this cause an infinite loop if I have 2 folders in a Collection and they have the same named requests. I was testing conditional workflows. In Cooper’s Meal Plan I created 2 folders: Example 1: TEST IF EXISTS, and Example 2: TEST IF NOT EXISTS. The requests are named the same in Example 1 and Example 2’s folders. I went into the collection runner and it just had an infinite loop.
So if I say in Example 1 folder, GetSomething (request name)
If ( data exists)
postman.setNextRequest(“Get App Test 2”);
So if I say in Example 2 folder, GetSomething (request name)
If ( data doesn’t exist)
postman.setNextRequest(“Get App Test 2”);
Is it problematic that the requests are named the same in Example 1 folder and Example 2 folder? If so, how do I specify the folder name in postman.setNextRequest method when specifying the request name?
So if we do this:
postman.setNextRequest (null);
Does this terminate the execution of all the test cases in the given folder under a collection or does this terminate the collection as a whole??
I hope this just terminates the execution of a folder under the collection. We have a structure where we have different API’s under each folder and we do setup calls at the start of each folder. Now if that setup fails we need to terminate just the folder for this API and move to the setup of the next API
Hi. I dont now if this was a question already…
how is it possible to fire a request in another folder? this is what I got….
#Folder A:
– R1: doSomething (<- pre-request script "if(!env.var){ setNextRequest("createDomain")}"
– R2: deleteDomain (should be skipped…)
#Folder B:
-R1: createDomain
-R2: doSomethingDiff
How to use pm.info.eventName can some give an example please
@ankit
Do you know: How to reuse a request in other request with arguments?
Hallo Ankit, this is a nice feature. However, I was wondering, is there a way of separating the workflow from the actual requests? I’m asking about this to improve on the re-usability of my requests. Right now, request A is determining what request B will be, trough pm.setNextRequest(). So all the “scenario navigation logic” is spread around all my requests. If I would like to use a specific request in, lets say 10 different scenario’s, that would create a lot of complexity. I.m.h.o. this is a bit of a violation of the separation of concerns principle. Is there a solution for this? E.g. having a js file where I put all my request navigation logic so that it’s separated from my actual requests I want to execute? Right now, this problem is actually holding me back on using postman as our main API testing tool for test automation.
I don’t have any need for this over engineered stuff. All I need is what you seem insistent on not providing: The ability to say “Before the current request runs, please run request xyz”. Thats all. Just a simple ‘before hook’ that will let me execute an auth request before trying to run any other request.