Saving a max value of counter to file in JMeter - testing

I'm using a SOAP/XML-RPC Request to test a WSDL. Additionally I created a Counter element for this request. Each call of one of the functions has to contain other value in one of parameters.
Is there any possibility to save the maximum counter value to the file?
So when I start test, the value will be loaded from the file and increase by the counter.
At the end, this max value will be again saved to this file. And so on, so on...

Let's drop the built-in Counter and pass around the thread safe AtomicInteger.
Add a setUp Thread Group with a JSR223 Sampler (choose groovy as a scripting language) to your test plan. We will use it to read the value from the file. This thread group will be executed before all other thread groups and will provide us with the initial value.
Add the following code to the sampler:
import java.util.concurrent.atomic.AtomicInteger
counter = new File($/C:\Path\ToFile\fileName.txt/$).text
ai = new AtomicInteger(Integer.valueOf(counter))
props.put("sharedAtomicInteger", ai)
Then add another JSR223 Sampler after SOAP/XML-RPC Request in your regular Thread Group.
Add the following code to the sampler:
ai = props.get("sharedAtomicInteger")
variable = ai.incrementAndGet()
vars.put("variable", Integer.toString(variable))
Now the value of the improvised counter is stored in a variable and can be used in other requests issued by this thread.
Add a tearDown Thread Group with a JSR223 Sampler to your test plan. This thread group will be executed after all other thread groups and will write the maximum value to the file.
Add the following code to the sampler:
ai = props.get("sharedAtomicInteger")
new File($/C:\Path\ToFile\fileName.txt/$).write(ai.toString())
Finally, your test plan should look like this:
setUp Thread Group
JSR223 Sampler
Regular Thread Group
SOAP/XML-RPC Request
JSR223 Sampler
tearDown Thread Group
JSR223 Sampler
P.S.
Bear in mind that for brevity's sake I used the put() method of java.util.Properties class which is discouraged in the documentation.

To save value into a file (assumes a JSR223 Element and Groovy language)
new File("value.txt").text = vars.get("foo")
To read the value from file (assumes __FileToString() function)
${__FileToString(value.txt,,)}

I used tips from the first comment and do it in the following way:
transfer - Simple Controller
reading transactionId - JSR223 PreProcessor
transfer - SOAPXML-RPC Request
saving transactionId - JSR223 PostProcessor
JSR223 PreProcessor
Script language: groovy
import java.util.concurrent.atomic.AtomicInteger;
initial = new File("${absolute_path}transactionid.txt").text;
initial = initial.trim();
ai = new AtomicInteger(Integer.valueOf(initial));
transactionId = ai.incrementAndGet();
vars.put("transactionId", Integer.toString(transactionId));
SOAPXML-RPC Request
Here I'm using transactionId as one of the parameters in the SOAP Request.
JSR223 PostProcessor
Script language: groovy
transactionId = vars.get("transactionId");
new File("${absolute_path}transactionid.txt").write(transactionId.toString());
${absolute_path} is a variable defined in test plan as:
${__BeanShell(import org.apache.jmeter.services.FileServer; FileServer.getFileServer().getBaseDir();)}${__BeanShell(File.separator,)}
It is a path to folder with this JMeter project. This folder also contains file which is read to this test case.

Related

Jmeter- Create HTTP request body using JSR223 Pre-processor

I am trying to dynamically create HTTP Request body for a POST by using JSR223 Preprocessor. Below is the code that I tried. But it is not working. Request body is populating as empty. Can anyone help?
def arg= new HTTPArgument("", dataToBePosted, null, true);
arg.setAlwaysEncoded(false);
sampler.getArguments().addArgument(arg);
I also tried
sampler.getArguments().removeAllArguments();
sampler.addNonEncodedArgument('',dataToBePosted,'');
Take a look at jmeter.log file, it might be the case you have a problem in your Groovy code, i.e. I fail to see dataToBePosted declared/initialized anywhere
Even if it is good it won't survive first iteration, I would suggest using Arguments class instance instead
Example code:
def data = new org.apache.jmeter.config.Arguments()
def body = new org.apache.jmeter.protocol.http.util.HTTPArgument('', 'dataToBePosted', '', false)
body.setAlwaysEncoded(false)
data.addArgument(body)
sampler.setArguments(data)
and demo:
More information on Groovy scripting in JMeter: Apache Groovy: What Is Groovy Used For?

Can i have a variable parameter in csv Data set configer in jmeter

This is my test plan where the first CVS data set configure is like
And the Second CSV data Set configure is like
I want to read a file that contains all the file names and go inside each file and read each line and form a http request and hit the server.
I don't want to use loop controller because i need concurrency in terms of requests in a single file.
Say the file1.csv contains 10 lines which is equals to 10 http calls and i have 5 threads then the threads have to handle the 10 calls concurrently
You cannot. CSV Data Set Config is a Configuration Element, as per documentation:
Configuration elements can be used to set up defaults and variables for later use by samplers. Note that these elements are processed at the start of the scope in which they are found, i.e. before any samplers in the same scope.
JMeter test elements execution order looks as follows:
0. Configuration elements
1. Pre-Processors
2. Timers
3. Sampler
4. Post-Processors (unless SampleResult is null)
5. Assertions (unless SampleResult is null)
6. Listeners (unless SampleResult is null)
So your ${file} variable will be null unless a Sampler is executed and 2nd CSV Data Set Config will be initialized before any sampler execution.
If you want to read data from files dynamically consider using __StringFromFile() or __CSVRead() functions instead.
Functions are being evaluated at the time they're being called so basically you can put a function anywhere in your script. Check out How to Pick Different CSV Files at JMeter Runtime article for more details if needed.

How to set variables to custom function in Jmeter?

I have a basic function in BeanShellSampler.bshrc at Jmeter 4.0
String getMyString(String strParam) {
return "MyString: "+strParam;
}
I called in BeanShell Sampler as below
String N = "123123";
log.info("${__BeanShell(getMyString("${__V(Var${N})}"),)}");
When I run Sampler output is somthing like that.
2018-06-18 15:25:40,080 INFO o.a.j.u.BeanShellTestElement: MyString: Var${N}
How can I set string variable to my function?
I read function articles in Jmeter web site
Thank you.
Add the next line to user.properties file:
beanshell.sampler.init=BeanShellSampler.bshrc
Amend your code to look like:
String N = "123123";
log.info(getMyString(N));
That's it, you should get MyString: 123123 in jmeter.log file
Be aware that starting from Jmeter 3.1 it is recommended to use Groovy for all forms of scripting as Groovy performance is much better comparing to Beanshell so consider taking the following steps instead:
Create a file, i.e. foo.groovy in "bin" folder of your JMeter installation and put your function there:
String getMyString(String strParam) {
return "MyString: " + strParam;
}
Add the next line to user.properties file:
You should be able to refer your custom code from __groovy() function like:
${__groovy(log.info(getMyString("123123")),)}
functions can be used anywhere in the Test Plan
For each BeanShell Program type there are different beanshell.*.init properties defined in bin/user.properties
beanshell.function.init=BeanShellFunction.bshrc
beanshell.preprocessor.init=BeanShellSampler.bshrc
beanshell.postprocessor.init=BeanShellSampler.bshrc
beanshell.assertion.init=BeanShellFunction.bshrc
Hence the same function which needs to be called from any program(preprocessor, postprocessor, etc) we need to copy the function to every .bshrc file OR use same .bshrc file for every program init property.
In your case if you are using local string variable N and passing it along with the script. If you use ${Variable} there must be a JMeter variable defined so that JMeter can pick its value. To do that you can use vars.put , write N value to JMeter variables and use ${N} .
I have defined Var123123 value as FinalValue as shown below
And 2 beanshell samplers one is to put String variable N to Jmeter variable and one is beanshell script as shown below
You can see in the log its printed VAR123123's value which is FinalValue
The reason why i took 2 beashell samplers is if i write N to JMeter variables and use it in same script its not updating N value until the sampler executed..
References :
Configuring JMeter
JMeter Beanshell
Please let me know if it helps

How to get value from property in BeanShell (jmeter)

I have got several thread groups. I want to use variable from the first group. In second group this var should be used in BeanShell.
So: in first thread group I created BeanShell Assertion with this code:
${__setProperty(erroriden, ${erroriden1})};
In second thread group I have BeanShell pre-processor.
If has line like this:
String[] erroriden = (vars.get("erroriden")).split(",");
I tried some variations like this:
String[] erroriden = (vars.get("__property(erroriden)")).split(",");
String[] erroriden = (vars.get("${__property(erroriden)}")).split(",");
but it doesn't work.
Please help to use ${__property(erroriden)} in BeanShell pre-processor.
In the first Thread Group:
props.put("erroriden", vars.get("erroriden1"));
In the second Thread Group:
String[] erroriden = props.get("erroriden").split(",");
JMeterVariables scope is limited to the current thread group only
JMeter Properties are usual Java Properties which are global for JVM instance
See How to use BeanShell: JMeter's favorite built-in component guide for more information on using Beanshell in JMeter.

BeanShell PreProcessor updates User define variables

I'm very new at JMeter issues.
In a test script i have a BeanShell PreProcessor element that updates some variables previously defined at a "User Defined Variables" element.
Latter those variables are used in "Http Requests". However, the value that is used in the http request is the default one.
The scripts seems to be working due to some debug print();
My question is if it's necessary to delay the script to be sure that the BeanShell finishes?
Thanks a lot for your attention
There is no need to put any delay to Beanshell Pre-Processor as it's being executed before request. I'd recommend to check your jmeter.log file to see if there are any scripting issues as Beanshell Pre-Processor does not report errors anywhere including View Results Tree listener.
There are at least 2 ways to assure that everything is fine with your Beanshell script:
Put your debug print code after variables replace logic to see if it fires
Use JMeter __Beahshell function right in your HTTP request. If it's ok - View Results Tree will demonstrate beanshell-generated value. If not - the field will be blank and relevant error will be displayed in the log.
Example test case:
Given following Test Plan structure:
Thread Group with 1 user and 1 loop
HTTP GET Request to google.com with path of / and parameter q
If you provide as parameter "q" following beanshell function:
${__BeanShell(System.currentTimeMillis())}
and look into View Results Tree "Request" tab you should see something like:
GET http://www.google.com/?q=1385206045832
and if you change function to something incorrect like:
${__BeanShell(Something.incorrect())}
you'll see a blank request.
The correct way of changing existing variable (or creating new if variable doesn't exist) looks like
vars.put("variablename", "variablevalue");
*Important: * JMeter Variables are Java Strings, if you're trying to set something else (date, integer, whatever) to JMeter Variable you need to cast it to String somehow.
Example:
int i = 5;
vars.put("int_i", String.valueOf(i));
Hope this helps.
You can update the vale of a "user defined variable".
You have to create a bean shell sampler
vars.put("user_defined_variable", "newvalue");
#theINtoy got it right.
http://www.blazemeter.com/blog/queen-jmeters-built-componentshow-use-beanshell
I'm new to jmeter too but as I know variables defined in "User defined variables" are constants, so you can't change them. I recommend to use "User Parameters" in preprocessors or CSV Data Set Config.