Open raghav19 opened 6 years ago
The gist of the request is, the iterations should run for a specific request or a set of requests and then no iteration is required, ,meaning control iterations at per request/multiple request level. Similar feature can be observed in ReadyAPI tool by SmartBear
@raghav19 You can make use of the powerful feature called postman.setNextRequest
(SNR)
I've prepared a collection to help you achieve this use-case very easily.
I've documented the scripts on how this can be done. (Take a look at Request 1
and Request 4
)
Not only this, setNextRequest allows you to build even more complex flows easily.
Here: https://www.getpostman.com/collections/75239d5577195dd82acf
To use this collection:
numberOfIterations
with the number of iterations you want. (You can skip in case you want to use the script to define the count viz. 5 and you can modify this in Pre-Request
script of Request 1
)Explanation of the collection:
Request 1
runs and sets the iterationCount.
On reaching Request 4
it checks if iterationCount is not the last one then jump to Request 1
Docs for SNR: https://www.getpostman.com/docs/v6/postman/collection_runs/building_workflows
You can think of SNR as basically like goto
and label
in C++
Let me know if this solved the issue for you. 🙂
Thanks @sivcan , for your valuable input. I am trying to implement the same using pm.info.iteration and pm.info.iterationCount. I added the following condition in my post request. I have only 1 POST request which has to run for multiple iteration of testdata.
if(pm.info.iteration != pm.info.iterationCount) { postman.setNextRequest('registerValue'); }
However even after calling as new request, the pm.info.iteration is not incrementing itself from 0 to 1. Where am i making a mistake?
Hi @sivcan ,
I tried further to get it working. i went through the exact same way as you have suggested in your example script. My POST & GET request are in a single folder. The use case is to run the POST request for all the iteration data and then call the GET request once. I observed the following with my execution.
The GET request gets executed even if i have set the next request in my pre-request Script of GET to call registerValue
.
Pre-request Script:
currentIterationCount = pm.environment.get('currentIterationCount'); numberOfIterations = pm.environment.get('numberOfIterations'); if(currentIterationCount < numberOfIterations) { postman.setNextRequest('registerValue'); }
When it calls the registerValue
POST request again , it is picking the first iteration data and not the new iteration data. As a result , my second iteration is failing the tests.
Please let me know , how to go about this
@raghav19 So,
Iteration should be 1 Also, the environment should be selected
How to share a collection
@raghav19 Also if you're using the data file, share a sample of that too.
Replace url's with postman-echo.com/post
and postman-echo.com/get
if you may. :)
@sivcan ,
Thanks for the input once again. The screenshots which you have show , I am very aware of the same and am running my requests and testing it out in the same manner. I have posted in the following link my collection as requested by you after removing all sensitive data.
The testdata which i am using is:
[ { "name":"Devuser", "address":"unknown", "value:": "hello" }, { "name":"Testuser", "address":"verymuchknown", "value:": "Bye" } ]
Observations:
@raghav19 Found the issue.
So, I'll explain what went wrong here.
Irrespective of 'where' you put the setNextRequest inside a request i.e inside pre-request script or tests script the current request will ALWAYS RUN and after the execution of the current request is finished only then the next request that you've request using the setNextRequest function will be executed.
You wrote the 'setNextRequest' function inside the pre-request script of the GET request, thus no matter what the GET request will be first executed and after it has finished, then the setNextRequest function will drive the runtime to the next request that is to be run.
So basically what happened was: Post Request > Get Request > Post Request > Get Request ... and so on
What was needed: Post Request > Post Request > Post Request > Post Request > Get Request (End Run)
To solve this, you need to put the setNextRequest function inside the POST request itself. So it'll keep checking after the execution of the POST request as to when do you want to use the GET request.
Read Advanced Workflows in the doc
Also,
Since we're not going to use 'iteration' feature of the runner but control the iterations on our own using the iterationCount variable and setNextRequest, thus pm.info.iteration
will not give you the current iteration count.
Something like this is happening:
let pm = { info: { iteration: 1 } };
for (let iterationCount = 0; iterationCount < 5; iterationCount++) {
console.log(pm.info.iteration); // This will always remain 1
console.log(iterationCount); // This is our loop modifying the iterationCount
}
Resolved Collection: https://www.getpostman.com/collections/aa8d42a00c4715e21b71
Now, using the data file would be tricky here. Since, we don't have the access to the complete data file's iteration data inside runner because of variable scopes being resolved per iteration.
You can do 2 things:
[
{
"iterations": [
{
"name": "Devuser",
"address": "unknown",
"value": "hello"
},
{
"name": "Devuser",
"address": "unknown",
"value": "hello"
},
{
"name": "Devuser",
"address": "unknown",
"value": "hello"
},
{
"name": "Devuser",
"address": "unknown",
"value": "hello"
},
{
"name": "Testuser",
"address": "verymuchknown",
"value": "Bye"
}
]
}
]
And then you can read in the test-script how we can achieve it.
Thanks a lot @sivcan for the solution. It works now. I went with option 2 for testdata iterations. However , now the POST request body needs data from the testdata. I tried with {{data.name}}. it doesnt work.. I think i have to save all the variables from testdata as env variables and then use it in the various places.
This also creates another problem, now that the structure of the testdata is changed. The further scripts also need to use it in the same fashion for this to work. But, other tests dont have such a scenario. It doest solve the problem elegantly..But yah..it does the job. The feature for controlling iterations at folder level is most essential. Let me know how to use the testdata.
Hey @raghav19, thanks for the writing in! I'm going to close this issue since the original issue is resolved. If you have any more questions, feel free to post them in the community: https://community.getpostman.com/
Cheers!
Nope, It isnt resolved, it just a workaround provided, which complicates many flows and script changes are required across the entire collection just because one request works in that fashion. That isnt scalable , please add this as a feature. If already added, please let me know the link for the feature release page
@raghav19 Found the issue.
So, I'll explain what went wrong here.
Irrespective of 'where' you put the setNextRequest inside a request i.e inside pre-request script or tests script the current request will ALWAYS RUN and after the execution of the current request is finished only then the next request that you've request using the setNextRequest function will be executed.
You wrote the 'setNextRequest' function inside the pre-request script of the GET request, thus no matter what the GET request will be first executed and after it has finished, then the setNextRequest function will drive the runtime to the next request that is to be run.
So basically what happened was: Post Request > Get Request > Post Request > Get Request ... and so on
What was needed: Post Request > Post Request > Post Request > Post Request > Get Request (End Run)
To solve this, you need to put the setNextRequest function inside the POST request itself. So it'll keep checking after the execution of the POST request as to when do you want to use the GET request.
Read Advanced Workflows in the doc
Also, Since we're not going to use 'iteration' feature of the runner but control the iterations on our own using the iterationCount variable and setNextRequest, thus
pm.info.iteration
will not give you the current iteration count.Something like this is happening:
let pm = { info: { iteration: 1 } }; for (let iterationCount = 0; iterationCount < 5; iterationCount++) { console.log(pm.info.iteration); // This will always remain 1 console.log(iterationCount); // This is our loop modifying the iterationCount }
Resolved Collection: https://www.getpostman.com/collections/aa8d42a00c4715e21b71
Now, using the data file would be tricky here. Since, we don't have the access to the complete data file's iteration data inside runner because of variable scopes being resolved per iteration.
You can do 2 things:
- Either you put the whole data file into an environment variable and you're good to go.
- You just modify you data file a bit like so:
[ { "iterations": [ { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Testuser", "address": "verymuchknown", "value": "Bye" } ] } ]
And then you can read in the test-script how we can achieve it.
Hi @sivcan,
I tried more towards what i wanted to achieve with my usecase, and i could come up with the following: I set the whole test data as a part of the pre-request script as follows
let testdataset =
[
{
"name": "Raghav",
"address": "abcd",
"value": "Hello"
},
{
"name" : "Santosh",
"address" : "defg",
"value" : "Mnop"
}
];
Now when running the request the pre-request script contains the following:
let testdataset = pm.environment.get("testdataset");
if (!testdataset)
{
testdataset =
[
{
"name": "Raghav",
"address": "abcd",
"value": "Hello"
},
{
"name" : "Santosh",
"address" : "defg",
"value" : "Mnop"
}
];
}
pm.environment.set("testdata",testdataset.shift() );
pm.environment.set("testdataset", testdataset);
The test script containers the following:
let testdataset = pm.environment.get("testdataset");
if(testdataset && testdataset.length > 0) {
console.log(pm.environment.get("testdata"));
postman.setNextRequest("POST REQUEST");
}
//Write tests below
As a result, i am able to run multiple iterations for my request with different data.
However, I couldn’t find a way for the following:
If this can be achieved , i can get consolidated reports for the whole collection with multiple customized test data requests folders in the same collection.
Kindly help, i think i am pretty close i believe. The link to my collection - https://www.getpostman.com/collections/8fafe1d9df0d95d6ddd0
@raghav19 Found the issue. So, I'll explain what went wrong here. Irrespective of 'where' you put the setNextRequest inside a request i.e inside pre-request script or tests script the current request will ALWAYS RUN and after the execution of the current request is finished only then the next request that you've request using the setNextRequest function will be executed. You wrote the 'setNextRequest' function inside the pre-request script of the GET request, thus no matter what the GET request will be first executed and after it has finished, then the setNextRequest function will drive the runtime to the next request that is to be run. So basically what happened was: Post Request > Get Request > Post Request > Get Request ... and so on What was needed: Post Request > Post Request > Post Request > Post Request > Get Request (End Run) To solve this, you need to put the setNextRequest function inside the POST request itself. So it'll keep checking after the execution of the POST request as to when do you want to use the GET request. Read Advanced Workflows in the doc Also, Since we're not going to use 'iteration' feature of the runner but control the iterations on our own using the iterationCount variable and setNextRequest, thus
pm.info.iteration
will not give you the current iteration count. Something like this is happening:let pm = { info: { iteration: 1 } }; for (let iterationCount = 0; iterationCount < 5; iterationCount++) { console.log(pm.info.iteration); // This will always remain 1 console.log(iterationCount); // This is our loop modifying the iterationCount }
Resolved Collection: https://www.getpostman.com/collections/aa8d42a00c4715e21b71 Now, using the data file would be tricky here. Since, we don't have the access to the complete data file's iteration data inside runner because of variable scopes being resolved per iteration. You can do 2 things:
- Either you put the whole data file into an environment variable and you're good to go.
- You just modify you data file a bit like so:
[ { "iterations": [ { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Devuser", "address": "unknown", "value": "hello" }, { "name": "Testuser", "address": "verymuchknown", "value": "Bye" } ] } ]
And then you can read in the test-script how we can achieve it.
Hi @sivcan,
I tried more towards what i wanted to achieve with my usecase, and i could come up with the following: I set the whole test data as a part of the pre-request script as follows
let testdataset = [ { "name": "Raghav", "address": "abcd", "value": "Hello" }, { "name" : "Santosh", "address" : "defg", "value" : "Mnop" } ];
Now when running the request the pre-request script contains the following:
let testdataset = pm.environment.get("testdataset"); if (!testdataset) { testdataset = [ { "name": "Raghav", "address": "abcd", "value": "Hello" }, { "name" : "Santosh", "address" : "defg", "value" : "Mnop" } ]; } pm.environment.set("testdata",testdataset.shift() ); pm.environment.set("testdataset", testdataset);
The test script containers the following:
let testdataset = pm.environment.get("testdataset"); if(testdataset && testdataset.length > 0) { console.log(pm.environment.get("testdata")); postman.setNextRequest("POST REQUEST"); } //Write tests below
As a result, i am able to run multiple iterations for my request with different data.
However, I couldn’t find a way for the following:
- How i can still give the data file and the iteration count for the collection as a whole in the collection runner?
- Using the above setting intact, run the specific request in the folder for only the set of iterations of test data provided as a part of pre-request script , meaning, the iteration count specified in the collection runner setting should not get applied for my specific request alone where test data is handled differently?
If this can be achieved , i can get consolidated reports for the whole collection with multiple customized test data requests folders in the same collection.
Kindly help, i think i am pretty close i believe. The link to my collection - https://www.getpostman.com/collections/8fafe1d9df0d95d6ddd0
Hi @sivcan , The updated link to my collection: https://www.getpostman.com/collections/8fafe1d9df0d95d6ddd0 So, once again on the usecase ,
Post_Service
folder , POST REQUEST should run for all the testdata mentioned in the pre-request script iteration data.Meaning, the Test
folder request , should be able to pick the test data from test runner data file whereas the Post_Service
folder should pick data from the iteration data that is set in pre-request script and only iterate through that.
I am trying to do something similar to what this thread is describing and having the same issue. I have looked at the collections that were posted and though they look like they work but unless I am missing something they are not answering the underlying question of why pm.info.iteration is not working. The documentation says
{pm.info.iteration:Number} Is the value of the current iteration being run.
but the code I am running show a different result:
console.log(pm.info.iteration);
if (pm.info.iteration === pm.info.iterationCount) {
postman.setNextRequest('request2');
} else {
postman.setNextRequest('request1');
}
The runner has an iteration set and when I log pm.info.iterationCount to the console it shows the value I expect but the pm.info.iteration variable is always zero and never increments.
So I would say either the documentation is wrong or there is a bug with pm.info.iteration See: https://learning.getpostman.com/docs/postman/scripts/postman_sandbox_api_reference
@adispennette A few things I'd like to point out, I might have misunderstood your use-case so feel free to explain further.
pm.info.iteration === pm.info.iterationCount
will never be equal since iterationCount
is the number of total iterations whereas iteration
starts from 0, so it'll always be equal to iterationCount - 1 and not more.
You want to check for pm.info.iteration === pm.info.iterationCount - 1
in your if statement.
Are you running specific iterations through the runner or are your iterations basically SNR performing actions?
pm.info.iteration
will only work with iterations that you pre-define before running the run.
Because only then the runner knows what is the total 'iterationCount' and what is the current 'iteration'. and following that, runner will perform the iterations (You can see in the runner UI it says 'Iteration 1', 'Iteration 2', and so on...).
In case you're using SNR, runner will never know what is the iteration / iterationCount since you're controlling it and guiding it to run the next request according to your code flow.
I can perform an infinitely running collection run using SNR, runner can never tell me what is the current 'iteration' and what is the 'iterationCount' in any way. SNR comes into action in real-time.
So in your case, I guess you've iteration count as 1 before running the run and you're performing the request execution completely through SNR.
That's why your iteration is always 0
and iterationCount will always be 1
.
The 'Iterations' input in the UI is your 'pm.info.iterationCount'.
Also, always remember to do pm.setNextRequest(null);
once you want your iteration (or collection run) to finish.
In case you had stated 2
as the iteration count before running the run then it'll perform the same actions twice.
You get the idea I suppose.
Let me know if I misunderstood you, I'll be happy to look into this further.
My new code based on your comments
console.log("pm.info.iteration = " + pm.info.iteration + " pm.info.iterationCount = " + pm.info.iterationCount);
if (pm.info.iteration === pm.info.iterationCount-1) {
postman.setNextRequest('request2');
} else {
postman.setNextRequest('request1');
}
The resulting console output
pm.info.iteration = 0 pm.info.iterationCount = 3
The Runner config:
and the "Run Results" which I stopped manually show:
Obviously I am missing/misunderstanding something. Based on how I am interpreting the documentation pm.info.iteration should be incrementing after every web service call executed in the runner until it is equal to pm.info.iterationCount-1.
What I am actually seeing leads me to believe that the pm.info.iteration will not increment until the entire collection is executed in its entirety, meaning that the collection completed its iteration and now the next iteration of the collection can commence.
So in its current implementation I believe what I need to do is skip the execution of a request based on the value of pm.info.iteration and allow the collection to complete for the pm.info.iteration to get incremented.
So the working code is:
if (pm.info.iteration === pm.info.iterationCount-1) {
postman.setNextRequest('request2');
} else {
postman.setNextRequest(null);
}
which results in only the last iteration moving on to the second and third requests in the collection.
@adispennette Import this collection in your postman app and please look at the 'Pre-request' script of 'Sample Request 1'. I have provided the steps and explanation there. Collection Link: https://www.getpostman.com/collections/1de22fd02391e6026f7b
Let me know if you still have any confusion.
Hi @sivcan thanks for the response. That collection is a bit overkill I think. All I needed was the condition on the iteration and count. So Request 1 checks pm.info.iteration === pm.info.iterationCount-1 and until that is true only the first request is executed. When it does finally evaluate to true I let it move on to the next request in the collection and from there just let the normal flow happen. it is a very simple use case and does not need all the other variables and checks.
@raghav19 You can make use of the powerful feature called
postman.setNextRequest
(SNR)I've prepared a collection to help you achieve this use-case very easily.
I've documented the scripts on how this can be done. (Take a look at
Request 1
andRequest 4
) Not only this, setNextRequest allows you to build even more complex flows easily.Here: https://www.getpostman.com/collections/75239d5577195dd82acf
To use this collection:
- Initialize an environment variable
numberOfIterations
with the number of iterations you want. (You can skip in case you want to use the script to define the count viz. 5 and you can modify this inPre-Request
script ofRequest 1
)- Run the Collection
Explanation of the collection:
Request 1
runs and sets the iterationCount. On reachingRequest 4
it checks if iterationCount is not the last one then jump toRequest 1
Docs for SNR: https://www.getpostman.com/docs/v6/postman/collection_runs/building_workflows
You can think of SNR as basically like
goto
andlabel
in C++Let me know if this solved the issue for you. 🙂
Hi,
I have used this setNext request function Ex: I have a request which need to run with 3 different value each time and i need to do different validation each time. How can i do that?
Thanks, Santhosh
I have a Rest API which is used for registering some data using POST request. In postman i have multiple data iterations that i run it for using collection Runner and all that data is updated successfully and validated. POST request response is as below. The id generated is dynamic and is saved in postman test script for each iteration using the 'pm.info.iteration' for each id for later use
Now i have another API which retrieves the whole list using a GET request.The validation scenario is to call the GET API once all the itearations are complete and validate the count and data.Is there a way to iterate on the data for POST request, after completion , call the GET request and check the count? How to achieve this when running with multiple folders and multiple tests inside each folder with dynamic data?