Using beanshell variable in subsequent While loop - jmeter

I need to use variable from beanshell in my while loop, but I am not able to see the value of variable coming through.
output variable of my JDBC select count(*) query is "count_num"
using following code in beanshell:
int id = Integer.parseInt(vars.get("count_num_1").trim());
Following is the structure of my test plan:
-JDBC request (o/p variable is count_num)
-beanshell sampler (parse string count_num to integer)
-While Controller: vars.get(${i})>0)
-http request1
-http request2
- (beanshell code to decrease "i" by 5 - not sure how??)
What am i doing wrong in usage of "i" and also how to decrease count of "i" by 5 towards the end of while loop.

Put variable string value after adding 5
vars.put("count_num_1", String.valueOf(id +5));

Related

Jmeter values mapping

How to achieve a kind of mapping between string and numeric values that can be used for comparison in assertion? Example:
MAP "DELIVERED"=0
"PENDING"=1
"WAITING"=2
sampler1 - extracted numeric_value=0
sampler2 - assert string value="DELIVERED" is equal to its numeric value
Please check the below test plan:-
I have used variable name from regular expression of 1st sampler in the switch controller like ${regVar}..Then used the second request 3 times i.e. 0,1,2 and used response assertion with the desired value like "DELIVERED"=0 for first sampler under switch i.e "0" then in second "PENDING"=1 i.e "1"..so on.
With this, based on the regEx value from 1st http sample, only one http request will be send for 2nd sampler and that request have it own assertion. I have tried with both positive and negative cases. Please change the assertion value based on your requirements.
Please check if it helps.
Be aware of JSR223 Assertion which allows you to use arbitrary Groovy code to define pass/fail criteria.
You can access the numeric_value using vars shorthand for JMeterVariables class like:
def numericValue = vars.get('numeric_value')
Example code:
def myMap = ['0':'DELIVERED', '1':'PENDING', '2':'WAITING']
def numericValue = vars.get('numeric_value')
log.info('Numeric value is: ' + numericValue)
log.info('Status is: ' + myMap.get(numericValue))
Demo:
More information: Scripting JMeter Assertions in Groovy - A Tutorial
Thanks Dmitri, implemented solution based on your suggestion and it suites fine.

How to read values from a database like a csv file in jmeter

I would like to read values from a select query and use the values sequentially in a API call.
Since the database values get stored as var_1, var_2 ... var_N
So how do i increment the number for the variable?
I used a counter and pre processor to increment the number in variable
vars.put ("email", "email"+"_"+vars.get("counter"))
But the final variable is not getting replaced by the value from the select query
eg select query result from a debug sampler
email_1=hata.pd.h13u#yopmail.com
email_2=hata.pd.h13u#yopmail.com
email_3=hataiot.test13#mailinator.com
email_4=hataiot.test12#mailinator.com
--combining the variable and counter:
vars.put ("email", "email"+"_"+vars.get("counter"))
--using the variable in the API post body
{
"username":"${email}",
"password":"test1234"
}
Actual result:
POST data:
{
"username":"email_1",
"password":"test1234"
}
Expected result:
{
"username":"hata.pd.h13u#yopmail.com",
"password":"test1234"
}
TIA
${__V(email_${counter})}
Try this one, see also the documentation: http://jmeter.apache.org/usermanual/functions.html#what_can_do
Note that variables cannot currently be nested; i.e. ${Var${N}} does not work. The __V (variable) function can be used to do this: ${__V(Var${N})}. You can also use ${__BeanShell(vars.get("Var${N}")}.
Have you considered using ForEach Controller? It's super-handy for iterating the variables from extractors or JDBC test elements.
If you still want to continue with the current approach you need to change this line:
vars.put ("email", "email"+"_"+vars.get("counter"))
to this one:
vars.put ("email", vars.get("email"+"_"+vars.get("counter")))
Because you're putting into email variable stuff like email_1, email_2, etc. instead of actual ${email_1} variable value.
References:
JMeter Functions and Variables
How to Retrieve Database Data for API Testing with JMeter

Jmeter- how to pass a fixed number of values from an array at a time until iterating through all values to a http request

In my get htttp request, I get an array of ids ex: list=[1, 2, 3.....1000]
And then for my next http request, I want to pass all the values in the list 10 at a time, so it will be 100 requests total and each time, it takes 10 values from the list array. I'm using a loop controller to call the http request 100 times. but I dont know how to retrieve 10 values at a time, and then go to the next 10, next 10 until all values are used.
How should I do that?
Add a regular expression extractor to your get request as a child.
Add the following properties shown in the screenshot to extract List
Add a Beanshell sampler/ JSR223 sampler and add the following code.
The code below creates a series of variables and store series of 10 values in a variable starting from Final_0 to Final_99
import java.util.Arrays
String complete_List=vars.get("List");
String[] complete_List_Array = complete_List.split(",");
int i;
for(i=1;i<=complete_List_Array.length;i++)
{vars.put("List_"+i,complete_List_Array[i-1]);}
int j;
int loopcount=complete_List_Array.length/10;
vars.put("loopcount",Integer.toString(loopcount));
for(j=0;j
{
StringBuilder sb = new StringBuilder();
sb.append("[");
for(i=j*10+1;i<=(j+1)*10;i++)
{
sb.append(vars.get("List_" + i));
if (i < (j+1)*10)
sb.append(",");
}
sb.append("]");
vars.put("Final_"+j,sb.toString());
}
vars.put("counter","0");
Add a loop counter and mention loop count as ${loopcount} as shown below
You can add HTTP Request as a child of loop counter and to pass series of 1o value at a time use ${__V(Final_${counter})}
Add a beanshell post processor to the http request to that will increment the counter
add the following code to the beanshell sampler
int counter = Integer.parseInt(vars.get("counter")) +1;
vars.put("counter",Integer.toString(counter));
You can see in the results its passing series of 10 values at a time and loop will run for 100 times
For more info on beanshell please follow the link
Please let me know if it helps.........
Considering you have the list array available at your disposal by using any extractor.
Extract the sublist from the array and put them in properties. Then, fetch the properties where ever you want it.
In the below I am fetching the sublist from the array and putting it in jmeter properties.
Here, I am fetching the values from the properties. This is just for demonstration and you dont need this. After putting list in properties just fetch in HTTP sampler as shown in the last image.
Now, to fetch it in HTTP sampler you can use loop and counter and fetch the properties using groovy. Loop for iteration and counter for increment the variable mylist_x.
Hope this helps.

jmeter unique id per thread for http request

My jmeter tests make a http request which contains a unique id.
http://myserver.com/{uniqueId}/
I want to set the base number (say 35000) and increment for each thread, for example my ids would be 35001, 35002, 35003 ...
http://myserver.com/{base + count}
I see functions for __threadnum and __counter but how would I:
set it in a variable so that I can substitute it in my url
add this count to my base value
I would simply go with Beanshell pre processor.
int threadNo = ctx.getThreadNum()+1; //to get the thread number in beanshell
int base = 35000;
int uniqueId = threadNo + base;
vars.put("uniqueId", Integer.toString(uniqueId));
Now your HTTP requests as given below should have the value substituted.
http://myserver.com/${uniqueId}/
To set a variable per thread you can use User Defined Variables.
To sum, you can use functions:
__intSum
__longSum
Or use a JSR223 PRE Processor or JSR223 POST Processor + Groovy and do it in Groovy.

Same random number and string for each thread

I need to generate the same JSON data twice for each thread for an HTTP request. I am having problem setting that up in JMeter.
My structure is:
Test Plan
- HTTP Header Manager
- Thread Group 1 users, 5 loop
- Random Variable,
- HTTP Request
I tried the combination of Per Thread User set to true and using seed for random function, but I can't achieve what I want. It keep on generating new number/string per loop.
Basically for each user, I want the exact same JSON request data.
I see three decisions for your case:
Use User Defined Variables before HTTP Request. Specify variables here. In this case it will be better to use __Random() function instead Random Variable.
Test Plan
- HTTP Header Manager
- Thread Group 1 users, 5 loop
- User Defined Variables, (Name:varName; Value:${__Random(1,100)})
- HTTP Request
Use Loop Controller (loop count=5) before HTTP Request (instead loop=5 in Thread Group)
I can suggest another solution which seems to me verbose and awkward but no other idea.
You create file using BSF (or BeanShell) PreProcessor and write value of random variable into file. Then read file before every request. In the next example I used Groovy and BSF PreProcessor.
import java.util.Random
def out= new File('File1.txt') // create file if it is not exists
if(!out.exists())
{
out.createNewFile()
Random rand = new Random()
int max = 10
def a = rand.nextInt(max+1)
out << a // write text to file
}
//then read value of generated variable
String fileContents = new File('File1.txt').text
//then put your variable into User defined Variable that I named HELLO
vars.putObject("HELLO",fileContents)
And in needed request use ${HELLO}

Resources