Jmeter beanshell sampler writing multiple lines - jmeter

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.

Related

how to write in csv ${__threadNum}${__time(ddMMyyyy,)}${__BeanShell(vars.getIteration();,)} in jmeter?

I am generating some unique number by combination of ${__threadNum}${__time(ddMMyyyy,)}${__BeanShell(vars.getIteration();,)}
now i want to write same number in csv or txt in jmeter.
I am using bean shell post processor for this.
Since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language
You should not be inlining JMeter Functions or Variables into Groovy scripts
Assuming above points here is the relevant Groovy piece of code
def first = ctx.getThreadNum()
def second = new java.text.SimpleDateFormat('ddMMyyyy').format(new Date())
def third = vars.getIteration()
new File('myFile.txt') << first << second << third
More information: Apache Groovy - Why and How You Should Use It
Use the below code:-
int random_var = ${__threadNum}${__time(ddMMyyyy,)}${__BeanShell(vars.getIteration();,)};
f = new FileOutputStream("D:/Output1.csv", true);
p = new PrintStream(f);
this.interpreter.setOut(p);
print(random_var);
f.flush();
f.close();
There are various ways but above is one example.For performance improvement it is recommended to use groovy.
Other help articles:-https://www.blazemeter.com/blog/saving-data-to-csv-files-with-java-through-jmeter
For groovy check:-https://stackoverflow.com/questions/51597623/jmeter-jsr223-sampler-unable-to-write-data-to-csv-file

Calling JSR223 Pre processor for each request

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)

how can i write jmeter map test case scenario with input and output result input is csv file out put should also csv file

I need to map my test case with the input data that is present in a csv file and compare it with rest response and generate a responce csv file with that perticular test scenerio in Jmeter.
So I am providing the deviceID as input and validating the json response and writing it into a csv file. for for single occurrence I can get the value as well as I can tag my test case in the response csv file. but when I try with multiple input with multiple test case my response came up returning the last value. like:
Validate  County ETR available with No Ticket April16PM Hurricane Event
lets say my input is:
Test Case Device ID Execution
Validate if Active Event 40122480 Yes
Validate if Valid Device ID 277136436 Yes
Validate  City ETR available with No Ticket 268698851
Validate  County ETR available with No Ticket 18515907
bean shell code is:
scenario = vars.get("ScenarioName");
eventname = vars.get("C_EventName");
eventtype = vars.get("C_EventType");
areaName = vars.get("C_AreaName");
areaType = vars.get("C_AreaType");
f = new FileOutputStream("C:\\RestService\\Result.csv", true); //specify true if you want to overwrite file. Keep blank otherwise.
p = new Print`enter code here`Stream(f);
this.interpreter.setOut(p);
print( scenario + ", " + eventname + ", " + eventtype + ", " + areaName + ", " + areaType);
f.close();
I have increse the number of threads to 4 but the loop count is 1.
can you please help me out. in this JMeter issue
I would not recommend going for Beanshell-based approach as if more than one thread (virtual user) will be writing into the same file the result will be unpredictable and most probably wrong as you are creating the race condition there.
The best option would be adding your variables to .jtl results file directly. To do this:
Add the next line to user.properties file (located in "bin" folder of your JMeter installation
sample_variables=ScenarioName,C_EventName,C_EventType,C_AreaName,C_AreaType
Restart JMeter to pick up the change
Next time you run your JMeter test in command-line non-GUI mode like:
jmeter -n -t test.jmx -l result.jtl
the resulting .jtl file will have 5 extra columns holding the values of the aforementioned variables for each request.
References:
Sample Variables
Configuring JMeter
Results file configuration

${__time} function output is incorrect

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")

read count of same response messages in thread group

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

Resources