I am using JSR223 Pre processor to generate UUID in http header. The value will be updated in a log file with timestamp for tracking purpose.
I have added the pre processor in each call, so every time it generates an unique value and updates the log file. Please have a look on below code.
import org.apache.jmeter.services.FileServer;
import java.sql.Timestamp;
import java.util.UUID;
String uuid = UUID.randomUUID().toString();
vars.put("p_x_transaction_id",uuid);
uid= vars.get("p_x_transaction_id");
String Logfile=vars.get("p_logfile");
f = new FileOutputStream(Logfile,true);
p = new PrintStream(f);
this.interpreter.setOut(p);
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
p.println(timestamp + " - " + uid);
Is it possible put above code in JSR223 sampler and call the method in header directly?
I have tried but it generates unique value for each iteration only.
Please throw some lights on this.
There is no need to copy and paste the JSR223 PreProcessor and add it to each call, the JSR223 PreProcessor obeys JMeter Scoping Rules so if you put it at the same level as all your Samplers - it will be applied to all the Samplers
As you can see I have only one instance of the JSR223 PreProcessor and it has been executed 3 times (before each Sampler in its scope)
Related
In my JMeter(5.1.1) script, I am trying to write into a csv file using BeanShell PostProcessor.
Where beanshell code is,
var name = "name";
var email = "email";
var currtime = "${__time(d-MMM-yyyy hh:mm:ss)}";
f = new FileOutputStream("D:/Temp/Temp.csv", true);
p = new PrintStream(f);
this.interpreter.setOut(p);
print(currtime + "," + name + "," + email);
p.close();
f.close();
It works but writes 3 lines in Temp.csv.
15-Nov-2020 05:16:32,name,email
15-Nov-2020 05:16:33,name,email
15-Nov-2020 05:16:34,name,email
Where only one line is expected to be written in CSV. Please suggest how to fix this error.
Your Beanshell PostProcessor is located on Thread Group level, it means that it's being run after every Sampler in its scope
If you want it to be executed after a certain Sampler - move the PostProcessor to be the child of this sampler
2.Since JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting.
If you run your test with >1 thread (virtual user) each user will be writing the lines into the same file and in case of concurrent writing you will face data corruption and/or loss due to the race condition so I would recommend considering switching to Flexible File Writer instead.
Hi All / Dimitri T Could you please post your valuable thoughts on extracting corresponding Values (For example ItemID1 and ItemSlot1) in one block of code randomly. I was able to write below Jsr223 postprocessor code and it is working fine. But when there are Blank spaces in ItemSlot id, then they are not fetching. From below code , i am passing ${rannum} under "Match No" in required regular expression.
Note: There will be more than 100 corresponding values. In some cases, we won't have ItemSlot1.i.e Blank/null values are appearing from server response. Hence, my script is not picking corresponding values.
Application Server Response:
"viewSaleListingLink": "https://Example.com/cars/item/search/-/listing/ItemID1/100011142",
"saleCountry": "",
"saleNote": "",
"bidLiveUrl": "https://Example.com/cars//registration?p_p_id=RegistrationPortlet_WAR_PWRWeb&p_p_lifecycle=1&p_p_state=normal&ItemSlot1=103009468",
JSR223PostProcessor Code
import java.math.MathContext;
import java.math.RoundingMode;
// Read occurance values from pervious response
def Max = Integer.parseInt( vars.get("ItemID1_matchNr"));
int min=1;
int rannum = min + (int) (Math.random() * ((Max - min) + 1));
log.info("Values id ="+rannum);
vars.put("rannum",rannum.toString());
enter image description here
If you need to extract a random match/pair of matches from the response using Regular Expression Extractor - it's sufficient just to provide 0 as the "Match No" and it will automatically fetch the random match group so you won't have to write any code:
Also be aware that Post-Processors are executed in the order they appear (upside down) so:
If your JSR223 PostProcessor is above the Regular Expression Extractor - ItemID1_matchNr will be undefined
If your JSR223 PostProcessor is below the Regular Expression Extractor - your rannum variable won't have any value
Also your response seems to be JSON so it makes sense switching to JSON JMESPath Extractor which is more powerful and convenient
I'm trying to get today's date using time function of jmeter with the format "${__time(yyyy-MM-dd)}" in BeanShell postprocessor. But after executing the Beanshell postprocessor the result shows as "1996". Basically the "time" function is displaying result by subtracting the values like "2018-03-19"=1996.
Please help me to resolve this issue so that i can get current date and time.
Beanshell code as below
import org.apache.jmeter.gui.GuiPackage;
import org.apache.commons.io.FilenameUtils;
String testPlanFile = GuiPackage.getInstance().getTestPlanFile();
String testPlanFileDir = FilenameUtils.getFullPathNoEndSeparator(testPlanFile);
vars.put("testPlanFileDir", testPlanFileDir);
//create the file in test plan file dir and print current time and Date
FileOutputStream f = new FileOutputStream(testPlanFileDir+"/CurrentDate.txt", true);
PrintStream p = new PrintStream(f);
this.interpreter.setOut(p);
//current date and time;
print("Current date is:"+${__time(yyyy-MM-dd)});
f.close();
Set time function call as parameter of your PreProcessor (by the way migrate to JSR223 + Groovy for performances)
And use it then with variable Parameters:
Try this with JSR223 PostProcessor and language Groovy and put this into script area:
def a = new Date().format('yyyy-MM-dd')
new File('Example.txt').withWriter('utf-8') {
writer -> writer.writeLine 'Current date is : ' + a.toString() }
(It works on JMeter 4.0)
You should move to JSR223 postprocessor according to JMeter Best Practices:
Since JMeter 3.1, we advise switching from BeanShell to JSR223 Test Elements
Until then you can fix it by quoting the function call as
print("Current date is:"+"${__time(yyyy-MM-dd)})";
This fix will treat the function's return value as string.
Currenty it treat it as a numeric substraction: 2018-3-19=1996 and then convert it to string
Performance anti-pattern #1: given you use GuiPackage class you won't be able to execute your test in non-GUI mode, consider migrating to FileServer instead
Performance anti-pattern #2: using Beanshell is not recommended as in case of high loads it might become the bottleneck. Since JMeter 3.1 it is recommended to use JSR223 Test Elements and Groovy language for any form of scripting
Performance anti-pattern #3: don't inline JMeter Variables or Functions in script body they break Groovy compiled scripts caching function and might resolve into something which will cause unexpected behaviour (like in your case), compilation failure or even data loss.
So:
Add JSR223 PostProcessor instead of the Beanshell one
Put the following code into "Script" area:
String testPlanDir = org.apache.jmeter.services.FileServer.getFileServer().getBaseDir()
File currentDate = new File(testPlanDir + File.separator + "CurrentDate.txt")
currentDate << new Date().format("yyyy-MM-dd")
I have thread group with single sampler.I have a scenario with 10 users to run for 1 hour duration. in view results tree showing different response data in every sampler's response data.can it possible to count how many times samplers get same response data.
{"success":false,"code":"104","message":"xx","status":412,"MessageType":"120","ResponseCode":"100","rilreplyDetails":"121"}
{"success":false,"code":"104","message":"yyy","status":412,"MessageType":"120","ResponseCode":"100","rilreplyDetails":"121"}
can I get a count of how many samplers get"xx" response,and how many for "yyy"?
One solution would be to define two variables in the Test Plan section, i.e: counter_xx and counter_yyy.
Then on the sampler request add one Regular Expression Extractor to extract the message value and finally use If Controller to specify which counter to increment.
The below image shows the structure for above solution.
Finally, you would be able to access the variable values by using ${counter_xx} or ${counter_yyy}.
The easiest would be doing this outside of JMeter, i.e. configure it to save response data by adding the next 2 lines to user.properties file:
jmeter.save.saveservice.output_format=xml
jmeter.save.saveservice.response_data=true
JMeter restart will be required to pick the properties up. Once your test is done inspect the resulting .jtl result file using your favorite XML editor.
See Configuring JMeter for more information on the approach.
Another option is using JSR223 Listener and the script like:
import org.apache.jmeter.engine.util.CompoundVariable
import org.apache.jmeter.functions.IterationCounter
def xxcounter = props.get("xxcounter")
if (xxcounter == null) {
xxcounter = new IterationCounter();
List<CompoundVariable> params = new ArrayList<>();
params.add(new CompoundVariable("false"));
xxcounter.setParameters(params);
}
def yycounter = props.get('yycounter')
if (yycounter == null) {
yycounter = new IterationCounter();
List<CompoundVariable> params = new ArrayList<>();
params.add(new CompoundVariable("false"));
yycounter.setParameters(params);
}
if (prev.getResponseDataAsString().contains('xx')) {
log.info('XX count: ' + xxcounter.execute(prev, sampler))
props.put('xxcounter', xxcounter)
}
if (prev.getResponseDataAsString().contains('yyy')) {
log.info('YYY count: ' + yycounter.execute(prev, sampler))
props.put('yycounter', yycounter)
}
The listener will scan current sampler response data and increment either this or that counter printing the current value to jmeter.log file.
Demo:
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It
Currently developing a script in jMeter, I need to retrieve x amount of values from a response then push those values into another HTTP request, here is the tricky part the response is a table which always changes (e.g. rows increase or decrease each time the test is run) so far I've created a Regex extractor which retrieves anything between the table now I need to create a beanshell post processor which retrieves the certain values from the variable retrieved by the Regex extractor and applies them to the HTTP request. I'm not to sure if this is the best way to do this so I am open to suggestions on doing this another way.
You need Beanshell PreProcessor applied to 2nd request, not PostProcessor applied to 1st request
I don't think that using Regular Expressions is a very good idea to parse HTML, I would suggest going for CSS/JQuery Extractor or XPath Extractor instead
Once you have required values in form of
var_1=foo
var_2=bar
var_MatchNr=2
You will be able to add these values to the 2nd HTTP Request like:
import java.util.Iterator;
import java.util.Map;
Iterator iter = vars.getIterator();
int counter = 1;
while (iter.hasNext())
{
Map.Entry e = (Map.Entry)iter.next();
if (e.getValue() != null)
{
if (e.getKey().toString().startsWith("var_") && e.getValue().toString().length() >0)
{
sampler.addArgument("param" + counter, e.getValue().toString());
counter++;
}
}
}