How can I add multiple values (these values are extracted with regex extractor) to a parameter.
I have the following test:
Using the regex extractor I get the following:
Now I'm using a BeanShell PreProcessor that contains the following code:
int count = Integer.parseInt(vars.get("articleID_matchNr"));
for(int i=1;i<=count;i++) { //regex counts are 1 based
sampler.addArgument("articleIds", "[" + vars.get("articleID_" + i) + "]");
}
Using this will generate the following request:
This will add multiple parameters with the same name (articleIds) which will cause an error when I'm running the test. The correct form of the parameter should be:
articleIds=["148437", "148720"]
The number of articleIds is different from a user to another.
That's totally expected as you're adding an argument per match. You need to amend your code as follows to get desired behavior:
StringBuilder sb = new StringBuilder();
sb.append("[");
int count = Integer.parseInt(vars.get("articleID_matchNr"));
for (int i = 1; i <= count; i++) {
sb.append("\"");
sb.append(vars.get("articleID_" + i));
if (i < count) {
sb.append("\", ");
}
}
sb.append("\"]");
sampler.addArgument("articleIds", sb.toString());
See How to use BeanShell guide for more details and kind of JMeter Beanshell scripting cookbook.
Related
I want to test a Get Request with list of values. I dont want to use CSV ,
so i started using Beanshell Preprocessor and has those values in Array. Then used for loop to use those values and send to Get Request in HTTP Request. Every this was Successful except sending values to Get request. It is reading all values and sending the last read value to Get request.
Question : I want my request to run for each value when code reads the data one by one.
var TtValuedetails;
int i;
n=22;
String[] ttvalue = {"34324324224","fdadsfadsf","dfdsfdsfds","dafadsfa",
"45435435","dfadsfads"
};
for(int i=0;i<n;i++)
{
if(i==0)
{
TtValuedetails=ttvalue[i];
if(ttvalue[0]=="34324324224")
{
vars.put("TtValuedetails",TtValuedetails);
log.info(TtValuedetails);
log.info("first value is executed" );
Org.Apache.......startRequest();
}
}
} ;
We cannot help you without seeing the full code and knowing what you're trying to achieve but one thing is obvious: you should not be using Beanshell, since JMeter 3.1 it's recommended to use Groovy for scripting.
Current problem with your code is:
ttvalue array contains 6 elements
n=22
the line TtValuedetails=ttvalue[i]; will cause failure on 7th iteration of the loop due to IndexOutOfBoundsException
If you want to send a request for each value of the ttvalue array the easiest is converting it into separate JMeter Variables like:
ttvalue_1=34324324224
ttvalue_2=fdadsfadsf
etc.
and using ForEach Controller for iterating the values.
Example Groovy code for storing the values into JMeter Variables:
String[] ttvalue = ["34324324224", "fdadsfadsf", "dfdsfdsfds", "dafadsfa",
"45435435", "dfadsfads"];
for (int i = 1; i <= ttvalue.size(); i++) {
vars.put("ttvalue_" + i, ttvalue[i - 1]);
}
I have a Jmeter (version 4.0) test script where I am using json extractor to fetch an array of strings from the response json using $..Names and storing it in a variable groupOfNames. The various names are stored like groupOfNames_1, groupOfNames_2, groupOfNames_ALL.
I need to make POST call next with body as
{
"name1", "name2", "name3" (--actual values--)
}
How can i achieve this using bean shell preprocessor? groupOfNames_ALL gives me all value but like this.... name1, name2, name3 (without quotes surrounding individual names). Please help. Thanks.
I heard Groovy is the New Black so you can add quotation marks around each of names as simply as:
vars.put('groupOfNames_ALL',vars.get('groupOfNames_ALL').split(',').collect {"\"$it\"" }.join(', '))
Demo:
Also as a gentle reminder: JMeter users are encouraged to use JSR223 Test Elements for any form of scripting since JMeter 3.1
Put the below code in your BeanShell PreProcessor:
int matchNr = Integer.parseInt(vars.get("groupOfNames_matchNr"));
for(int i = 1; i <= matchNr; i++){
String Names = vars.get("groupOfNames_" + i);
if(i == matchNr){
vars.put("AllNames", vars.get("AllNames") + "\"" + Names + "\"");
}
else if(i == 1){
vars.put("AllNames","\"" + Names + "\", ");
}
else{
vars.put("AllNames", vars.get("AllNames") + "\"" + Names + "\", ");
}
Then use the variable ${AllNames} in your post as below:
{
${AllNames}
}
I have a Jmeter test in which I want to post an XML message to a JMS queue. This message will be formed dynamically via a BeanShell Preprocessor, which pulls data from multiple CSV Data Set Config elements.
One item of this XML message that is dynamic is the number of elements in it - it will be a random number between 1 and 10. For each Line element, I want to pull a different variable from a CSV Data Set Config element. However, I'm finding if I do something like the below, I keep getting the same variable:
for (int i = 0; i < numberOfLines; i++) {
InputXML = InputXML + "<OrderLine ItemID=\"${ItemID}\" />";
}
The above will keep using the same ${ItemID} variable for all of lines but what I want is for it to grab the next one in the CSV file.
Is there any way to accomplish this via Beanshell?
To go along with your data, if CSV looks like (first row will saved as variables)
0,1,2,3,4,5,6,7,8,9
a,b,c,d,e,f,g,h,i,j
The Beanshell will use index i to get value of column i in CSV:
String InputXML = "";
for (int i = 0; i < 10; i++) {
String a = vars.get(String.valueOf(i));
InputXML = InputXML + "<OrderLine ItemID=\"" + a + "\" />";
}
vars.put("InputXML",InputXML);
InputXML variable will hold the full value.
If you want random value until 10, you can use JMeter function ${__Random(0,10,myRandom)}.
If you want to get random line in CSV you can use the similar answer.
I have this filtered JSON response from Json Path exression
[40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,45,45,45,45,45,42,45,42,45,42,41,40,35,37,35,45,42,41,40,35,37,35,45,42,41,40,35,37,35,45]
I need to write some assertion which will basically assert these values are in a range ex: between 30 and 60.
I am not getting any pointers on how to assert this in jmeter.
JMeter doesn't offer appropriate Test Elements so you will have to do some scripting.
The below code assumes JMeter version is equal or higher than 3.0. For earlier JMeter versions you will have to put Json-smart libraries somewhere in JMeter Classpath
Add Beanshell Assertion after the JSON Path PostProcessor
Put the following code into the Beanshell Assertion "Script" area
import net.minidev.json.JSONArray;
import net.minidev.json.parser.JSONParser;
import org.apache.commons.lang.math.IntRange;
String source = vars.get("yourVar");
IntRange range = new IntRange(30, 60);
JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE);
JSONArray array = (JSONArray) parser.parse(source);
for (int i = 0; i < array.size(); i++) {
int value = (int) array.get(i);
if (!range.containsInteger(value)) {
Failure = true;
FailureMessage = "Detected value: " + value + " is not in the expected range";
}
}
If the value outside the given range will be found the Beanshell Assertion will fail the parent sampler
See How to Use BeanShell: JMeter's Favorite Built-in Component article for more information on enhancing your JMeter tests with scripting.
I have following entries that got extracted from Response using JSONPath extractor
entries = ["e-1553","e-1552","c-1052","e-1551","c-1050",
"e-1550","c-1049","e-1549","c-1051","e-1548",
"c-1048","e-1547","c-1047","e-1546","c-1045",
"e-1545","e-1544","c-1046","e-1543","e-1542",
"c-1026","e-1541","e-1540","e-1539","e-1538",
"c-1025","e-1537","e-1536","c-1024","f-1535",
"f-1534"]
I want to Iterate only over those entries that start with "e-" e.g. "e-1553,e-1552" etc. in my ForEach Controller and exclude other entries such as "c-1052, c-1050" etc.
So that I can use http://somesite.com/e-1553 etc.
How do I do that?
Given you have "entries" variable which holds that JSONArray you can get all the entries which start from "e-" as follows:
Add a Beanshell PostProcessor after the JSONPath Extractor
Put the following code into the PostProcessor's "Script" area:
JSONArray array = JSONArray.fromObject(vars.get("entries"));
int counter = 0;
for (int i=0;i < array.size();i++) {
String s = array.get(i).toString();
if (s.startsWith("e-"))
{
counter++;
vars.put("entry_" + counter, s);
}
}
It will produce variables like:
entry_1=e-1553
entry_10=e-1544
entry_11=e-1543
entry_12=e-1542
entry_13=e-1541
etc.
Then add ForEach Controller and configure it as follows:
Input variable prefix: entry
Start index for loop: 0
Output variable name: current_entry
Then in HTTP Request use ${current_entry} in the Path.
See How to use BeanShell: JMeter's favorite built-in component guide for more information on Beanshell scripting in JMeter.