I have a requirement to load the dynamic assets(Images) parallelly which got extracted from the for each loop as there is only one sampler with variable passed. I cant use the parallel controller here, also I don't know the exact number of assets loaded to pass in parallel sampler.
As suggested by you in one of similar issues I have used that approach(add pre sampler) below script and try to execute it in, It is able to pick the values but the child element is always only one(Parallel requests are not happening) however I see the URL's passed main request has multiple passed.
Pre-Processor script used:
String var2 = vars.get("tokens");
String var3 = vars.get("Token");
vars.put("var3", "https://stagingassets.ovid.com"+"/"+var2+"/t/width-150-png?"+var3);
urlsList = vars.get("var3").tokenize(",")
for (int i = 0; i < urlsList.size(); i++) {
def row = new org.apache.jmeter.testelement.property.CollectionProperty()
row.addItem(urlsList[i])
sampler.data.addItem(row)
log.info("ROWS ${row}")
}
variables are coming from CSV where values are saved into a file from each loop using a Flexible File Writer.
please suggest , My requirement is to execute the images parallelly as it happens in the browser.
[JMeter script image][1]
Use Parallel Sampler, the URLs can be added dynamically via JSR223 PreProcessor using the following code snippet:
sampler.addURL('your-first-url')
sampler.addURL('your-second-url')
If you want to mimic browser-like behaviour you need to put the Parallel Sampler under the Loop Controller and set the number of loops to the number of your URLs / 6
Related
How can i store extracted value of a variable in a csv/text file using JSR223 post processor
If this is something you really need to do in the JSR223 PostProcessor the minimal code would be:
new File('/path/to/your/file.csv') << vars.get('YOUR_VARIABLE_NAME_HERE') << System.getProperty('line.separator')
However if there will be a minimal concurrency you will run into the race condition when 2 or more threads (virtual users) will be writing into the same file resulting in data corruption
The approach which I would recommend is using:
Declare the variable you want to store via Sample Variables JMeter Property by adding the next line to user.properties file (lives in "bin" folder of your JMeter installation):
sample_variables=YOUR_VARIABLE_NAME_HERE
Once done you will be able to write the values using Flexible File Writer configured like:
You basically need to write the code to write into file.
Something like:
import org.apache.commons.io.FilenameUtils;
attr1 = vars.get("attr1");
attr2 = vars.get("attr2");
f = new FileOutputStream(locationOfCSVOutputfile, true);
p = new PrintStream(f);
p.println(attr2+","+attr2);
p.close();
f.close();
Like wise get the values you need and write into the file by comma separated.
Beware that in multiple threads scenario, Many threads will be accessing same file. therefore the file output may not be what you expected. To overcome this I used a critical section controller.
Hope this helps.
1/ Consider for example a node in your test plan with your request :
A regular expression extractor and a JR223 post processor component as child of your request.
2/ If you extract for example a multiple variable named "blabla" positioning the match number to "-1"
3/ Here's the piece of Groovy code that you can use in your post processor component to write your variable in a file :
import org.apache.jmeter.*;
File outputFile = new File("MY_FILE.csv")
int max = Integer.parseInt(vars.get("blabla_matchNr"));
for (i=1;i<max;i++) {
def word = vars.get("blabla_"+i);
outputFile << word << "\r\n"
}
I'm making extensive use of JMeterVariables/vars in my current JMeter code- in particular I'm generating variable names dynamically, based on JSON input.
Is there any way of getting the program to kick out a list of every single variable that is stored in vars??
Thanks!
You can do one of the following:
Add Debug Sampler in your script, with JMeter Variables = true
Similarly, add Debug Post-Processor under the sampler which creates dynamic variables
Since vars is just a regular Map, you can iterate it using one of the scripting languages (BeanShll, Groovy, etc):
for(java.util.Map.Entry<java.lang.String,java.lang.Object> var in vars.entrySet())
{
log.info(var.getKey() + "=" + var.getValue().toString());
}
Note that some variables are objects, so their representation will depend on how toString() function is implemented for them.
Add JSR223 Sampler to your Test Plan
Put the following code into "Script" area:
vars.entrySet().each { var ->
log.info(var.getKey() + '=' + var.getValue())
}
All the variable names and values will be printed to jmeter.log file
More information: Apache Groovy - Why and How You Should Use It
I'm trying to create a simple counter that will print the iteration number to the log.
the problem is that I didn't find a way to initialize the int value of i to 0.
if I'll do it inside the Beanshell script it will keep initializing, I need it to run only once at the beginning of the test.
My code:
int i=0;
log.info(string.valueOf(i));
i=i+1;
Add Once Only Controller, under it JSR223 Sampler with the initialization
vars.putObject("i", 0);
Then you can increment it after it (not under the Controller) with other JSR223 Sampler:
myI = vars.getObject("i")
log.info(String.valueOf(myI));
vars.putObject("i", ((Integer)myI+1));
It is recommended to avoid scripting where possible, and if you cannot live without scripting you should be using the most performing option which is JSR223 Test Elements and Groovy language.
Particularly your case can be implemented without any scripting, you can use the following JMeter Functions:
__log() - which prints an arbitrary message to jmeter.log file
__iterationNum() - which returns the number of current iteration
So if you use the statement like: ${__log(Current iteration is: ${__iterationNum},,,)} JMeter will return it where the function is called and additionally print the corresponding message to the log file.
Demo:
You can install __iterationNum() function as a part of Custom JMeter Functions bundle using JMeter Plugins Manager
I am trying to create a jmx to test some database entries. The exact queries are not known beforehand and need to be picked from one of many sets of queries, that I have declared in separate pre-processor units.
For eg. one of the set of queries is:
String[][] animals = new String[][]{
{"VLS_CATS_ASSOC","CAT_ID_AS = '${CAT_ID_AS}'"},
{"VLS_DOGS_EXCH","DOG_ID_ST = '${DOG_ID_ST}' and DOG_TXT_REF = '${DOG_TXT_REF}'"},
};
The 2D array has two entries, the 'table name' and the 'where clause'
So, the jdbc request is select * from ${table_name} where ${where_clause}
I've set up a loop controller for iterating through the tables one by one, and as a child i have jdbc sampler, that has the csv table config which will contain data for CAT_ID_AS, DOG_ID_ST, DOG_TXT_REF.
Currently, when i see my requests through a results listener, i see that the queries sent are:
select * from VLS_CATS_ASSOC where DOG_ID_ST = '${DOG_ID_ST}' and DOG_TXT_REF = '${DOG_TXT_REF}'
It is clear from the output that the first level of substitution has worked, but not the second one.
Can anybody please help me on this?
Edit: Adding an image of the test plan. Jmeter Test Plan
Don't use ${CAT_ID_AS} notation in (I presume) the BeanShell strings: while it is generally working, that's an undocumented and error-prone feature.
The legit way is vars.get("CAT_ID_AS")
vars is a pre-defined object available in any BeanShell piece inside your test plan
So your code would be looking like
String[][] animals = new String[][]{ {"VLS_CATS_ASSOC","CAT_ID_AS = '" + vars.get("CAT_ID_AS") + "'"}, ... etc
I am writing a jmeter script that keeps loading data until a table reaches a specified size. I have a while loop, in which I have one HTTP Sampler to loads the data, then another HTTP Sampler with an XPath Post-processor to check the table size (they call two different APIs). The reference variable of the XPath Post Processor is currentSize and I have a user defined variable maxSize, but using ${currentSize} < ${maxSize} as the condition for the while loop creates an infinite loop.
Thinking maybe the problem is that the output of XPath is a string, I've tried doing various things in beanshell to coerce it to a number, but I'm a beanshell noob, so I haven't been successful with that either. Can anyone guide me about how to get jmeter to recognize a variable as a number? (Preferably a decimal, but if I have to round to an int, I can live with that.)
Thanks!
I think using __javascript(parseInt()) should suffice for you to check the condition.
e.g.
${__javaScript(parseInt(${time_elapsed_string}) < parseInt(${duration}))}
Assuming that you have following variables:
currentSize
maxSize
continue
where continue is set via User Defined Variables and has the value of true
You can use following Beanshell code to check if current size is equal or greater than maximum size:
import java.math.BigDecimal;
String currentSize = vars.get("currentSize");
String maxSize = vars.get("maxSize");
BigDecimal currentSizeNumber = new BigDecimal(currentSize);
BigDecimal maxSizeNumber = new BigDecimal(maxSize);
if (currentSizeNumber.compareTo(maxSizeNumber) > -1){
vars.put("continue", "false");
}
Make sure that following criteria are met:
Your While Controller has ${continue} as a condition
Beanshell Sampler, Pre / Post Processor or Assertion with the code above is added as a child of the While Controller
See How to use BeanShell guide for more details and kind of Beanshell cookbook.
Everything should work this way.
Hope this helps.