How to increase Variable value based on the iteration being run in Postman - postman

I have an API request that I need to run in Postman-Collection-Runner thru multiple iterations. The API request uses Variable.
How can I make this variable to automatically increase with each iteration (or maybe set the iteration value as another Variable)?

If I understand your question correctly, you would like to assign different values to a variable in the request in different iterations which is achievable in 2 ways.
a) Using data files
https://learning.getpostman.com/docs/postman/collection_runs/working_with_data_files/
The data files could be in JSON or CSV format. Unfortunately, there is no way in Postman to tie the variable values to another variable unless you want to do it in a hacky way!
b) Pre-request & Tests scripts
1- Initialise the environment variable in the Pre-request Scripts like this:
var value = pm.environment.get("var");
if( !value) {
pm.environment.set("var", 1);
}
2- Increment the variable value in Tests
var value = pm.environment.get("var");
pm.environment.set("var", value+1);
This creates an environment variable and increments it after each iteration. depending on how you structure your collection you might need to consider flushing/resetting the environment variable to be ready for the next run
It worth mentioning that Pre-request Scripts and Tests running before and after the requests respectively, so you can write any scripts that would like to run after the request in the Tests. It shouldn't be necessarily a test!

1. Using Global pm.* functions and Variables in Pre-Request Scripts/Tests
Pre-Request script - runs before executing the request
Tests - runs after executing the request
a.
pm.variables.set("id", pm.info.iteration);
Ex: example.com/{{id}}/update gives
example.com/0/update
example.com/1/update etc...
Number of iterations is set in Collection Runner. pm.info.iteration key has the current iteration number, starting at 0.
b.
var id = +pm.globals.get("id");
pm.globals.set("id", ++id);
The variables can be in any scope - globals/collection/environment/local/data.
In Collection Runner, check the Keep Variable Values checkbox, to persist the final value of the variable in the session (here id).
Note: If the variable is accessed via individual scopes (via pm.globals.* or pm.environment.* or pm.collectionVariables.*), then the mentioned checkbox should be toggled as required. Else if accessed via local scope (pm.variables.*), the value will not be persisted irrespective of the checkbox.
Ex: Same as above
More on variables and scoping
2. Using Dynamic variables
These variables can be used in case random values are needed or no specific order is necessary.
a. $randomInt - gives a random Integer within 1 - 1000.
Ex: example.com/{{$randomInt}}/update gives
example.com/789/update,
example.com/265/update etc...
b. $timestamp - gives current UNIX timestamp in seconds.
Ex: example.com/{{$timestamp}}/update gives
example.com/1587489427/update
example.com/1587489434/update etc...
More on Dynamic variables
Using Postman 7.22.1, while answering this. New methods may come in future.

Related

how i can add multiple values in one variable in postman?

i need to run only one request with 4 sets of data, rest all requests i want to run one time so iteration is not an option for me. the request is get and i want to pass multiple values in one of the parameter of get request. want to run script for those many times like if 4 values in variable script should run 4 times. How i can add 4 values in one global parameter? secondly how to later use that parameter to run that many times?
pm.globals.set('my_var', JSON.stringify('["iphone", "ipad"]'))
for ( i=1; i<= 4; i++)
{
console.log (JSON.parse(pm.globals.get('my_var'))[0].value);
}
This is returning me [ as value as [ is present at that point but i want to make it read whole value which is iphone. Please guide

JMeter repeat Regular Expression extractor for all requests

I have a JMeter script that goes through a bunch of requests, each being different, GETs, POSTs and so on...
Each request returns a custom header from the server that has some numeric values in it. This header returns the actual processing time it took on the server side (without latency/http overhead)
I was able to add a Regular Expression Extractor to get that value from the header without any problems, however I would like this to be repeated for all the requests.
By using Debug Sampler I can see that the extractor only runs once, seems to be the last instance.
How can I have an extractor that runs all all requests and collects all the values from the header.
Bonus question. Finally I would love to be able to aggregate these values and get one average value.
Disclaimer: This other question is similar to mine but it doesn't explain how to actually do it in terms of the locations of the extractor and the debug sampler.
Track results of a regular expression extractor in JMeter
Thank you.
Just put Regular Expression Extractor at the same level as your HTTP Request samplers and it will be applied to all of them
See Scoping Rules User Manual entry for more detailed explanation.
With regards to value collection the best option is using Sample Variables property. Given you store your header value into a variable called ${foo} you can get it appended to jtl results file by adding the next line to the user.properties file:
sample_variables=foo
JMeter restart will be required to pick the property up. The other way (which doesn't require restart) is passing the property via -J command-line argument as
jmeter -Jsample_variables=foo -n -t test.jmx -l result.jtl
As the result you will get an extra column called foo in the .jtl results file and it will hold the ${foo} variable value for each Sampler. Upon test completion you will be able to open .jtl results file with MS Excel or equivalent and use AVERAGE function to get the value you're looking for.
See Apache JMeter Properties Customization Guide for more information on setting and amending various JMeter properties for Configuring JMeter according to your needs.
While Dmitri's answer is one way of doing it. But I wanted something different than each time exporting it into a file and post processing it...
I ended up doing this "manually"
By manually I mean I added a BSF Assertion with language = JavaScript and then wrote some JavaScript to do this:
Pull the value out of the header (if found)
Keep a record of total/count using variables
Updating a variable that shows the aggregate always
Add Debug Sampler to get easy access to the values after the test.
The following is the code that I used in the BSF Assertion:
var responseHeaders = prev.getResponseHeaders();
var xNodetasticRt = /x-nodetastic-rt: (\d+\.?\d*)/.exec(responseHeaders);
if (xNodetasticRt) {
var value = parseFloat(xNodetasticRt[1]);
vars.put("xNodetasticRt", value);
var total = parseFloat(vars.get("xNodetasticRt-Total"));
if (!total) {
total = 0.0;
}
total += value;
vars.put("xNodetasticRt-Total", total);
var count = parseFloat(vars.get("xNodetasticRt-Count"));
if (!count) {
count = 0;
}
count++;
vars.put("xNodetasticRt-Count", count);
vars.put("xNodetasticRt-Average", total / count);
}

Sequence generator with aggregator

Data is being passed through an aggregator transformation and grouped by customer account number to ensure I have distinct values. This is then passed to an expression transformation. I have a sequence generator transformation linked to the expression transformation - it never touches the aggregator. A variable in the expression is populated with the sequence number.
The problem I am running into is that the variable is coming up with a value in excess of the sequence number - e.g if there are 499 rows, the value of the variable is 501. It's as though the value assigned to the variable is ignoring the grouping and returning a non-distinct count.
Any idea what's happening here?
edit: More info on how this is being done. (Can't screenshot as it's too big.)
Flow 1 takes a list of account numbers, service numbers and destination systems and uses a router to sort them into flat files by destination system.
123456|0299999999|SYSA
123456|0299999999|SYSB
123457|0299999998|SYSA
123457|0299999998|SYSB
123457|0299999997|SYSA
123457|0299999997|SYSB
Some systems don't want the service number and some do. For those that do, it's a simple exercise of routing them through an expression transformation to set the variable using the sequence number. So the required output for SYSA would look like:
123456|0299999999|SYSA
123457|0299999998|SYSA
123457|0299999997|SYSA
And the expression transformation sets the variable using:
SETVARIABLE($$SYSA, SEQUENCE_NO)
In a second flow, I construct header and trailer files. For the trailer record count, I simply output the current value of $$SYSA like so:
SETVARIABLE($$SYSA, NULL)
I use Target Load Plan to execute the second flow only after the first completes.
I can demonstrate that using the variable in this way works, because the workflow outputs the correct values every time - I can alter the source datato increase or decrease the number of rows, and the value output for $$SYSA in the second flow is correct the first time (i.e it can't be a persisted value).
Where this is falling down is when the destination system only wants distinct account numbers and no service numbers. The required output for SYSB would be:
123456|SYSB
123457|SYSB
i.e the third row for SYSB is discarded because the account number is not unique. I'm trying to achieve this by putting an aggregator between the router and the expression, and grouping by the account number. However the $$SYSB variable isn't being assigned correctly in this case.
It appears Informatica was only updating the value of the variable if it is higher than the persistent value stored in the repository. So if a successful run persists a value of 501 to the repository, that value is picked up again at the start of the next run and it's only overridden if the new value is higher. I worked around it by declaring a starting value of 0 in the parameter file.

Is there a way to access the iteration number in Postman REST Client?

I'm using postman for API testing. I'm running a large number of tests and I want to print the iteration number to the console on some of them. Is there a way to get the iteration number as an environment-like variable?
According to Postman API Reference, pm.info.iteration - is the value of the current iteration being run.
Example:
console.log(pm.info.iteration);
It is possible now! You can access the iteration variable, in the same way you access other variables like responseBody.
I don't know if there is an internal way to get the iteration number but I believe you should be able to track this number through code yourself. Here's a quick code snippet:
var value = environment.count;
value++;
postman.setEnvironmentVariable("count", value);
If you put this in the pre-request editor or the test editor of a collection that you are sure will run once per iteration it will effectively track the iteration count.
You can get the iteration number with
pm.info.iteration:Number
Is the value of the current iteration being run.
Postman Sandbox API reference
I got there like this:
const count = pm.info.iteration+1
console.log("======== LITERATION "+count+" ========");

Biztalk mapping inline script global not updated

Good afternoon,
The problem:
I'm trying to count output nodes in a biztalk mapping.
I don't want to use the record count functoid or a xslt transformation since there are a lot of conditions that determine if the node is generated.
What I tried:
I created a script functoid and declared a global variable (in C#).
// global to save count
public int E1_Record_Count = 0;
I created a script functoid to output the global variable and tied it to my output node:
public string E1_Records()
{
return E1_Record_Count.ToString();
}
I created a script functoid and that is connected to the logical functoid that controls if a node is produced. This script counts the number of nodes created:
public void IncrementE1Count( string isOutput )
{
try
{
if ( System.Convert.ToBoolean( isOutput ) )
++E1_Record_Count;
}
catch
{
}
}
What doesn't work:
I always get zero as result. I've changed the global declaration and the output changes so the global seems to be declared, initialized and output correctly. Creating a second declaration for the global throws an error so there's only one global instance of the variable.
I commented out everything but the increment line in the script to change the global. This makes me think it's never being executed. This script functoid is tied to the same logical functoid that controls the output nodes (which I do get).
Any ideas what's going wrong?
I'm using Biztalk Server 2010.
Since the script functoid had no output the new xslt 2 evaluator used in biztalk 2010 optimized away any calls to it.
If I add a output value and connect the script functoid containing the increment function to an output node then it gets called and it works.
Any output from this function has no value since the count of nodes will be incomplete when it's called. So I need to output something, but I have nothing of any value. I changed the function to return a constant string which I used to set a node that required a constant value.
It's not a nice hack but I don't see any other easy way to trick xslt into evaluating it.
I believe I've solved something similar to this years ago by setting a value BEFORE the mapping and/or doing the counting outside of the mapping. Depending on XSLT (the mapper) for keeping state (counts, etc.) is something I just try to avoid. Probably not the answer your looking for, but I use .NET helper classes way more than trying to out trick XSLT and the mapper.
I found it was simplest to create an orchestration and use two sequential transformations to count the nodes.