How to generate multiple jmeter sampler results from a BSF Sampler? - jmeter

I have a BSF sampler that runs a groovy script.
I want to create multiple sample results out of this single script in jmeter.
Is it possible?

...my groovy script will run a junit suite and i want to report each junit test separately. Or my groovy script will make 100 http get and i want to display 100 sampler results.
To achieve this you have to organize loop - e.g. put your BSF Sampler under any suitable logic controller: Loop Controller), While Controller, ForEach Controller, or use possibilities of Thread Group (Loop Count, Number of Threads fields).
This scenario will re-use single instance of your BSF Sampler for each new iteration / thread and produce separate sampler result for each execution.
As well you possibly have to provide different entry data / params to BSF Sampler on each iteration - to parametrize it. In this case you can look at least into CSV Dataset Config (to read from file) or any of postprocessors/extractors (go get data from responses).
Suppose you also look into JSR223 Sampler to use along with groovy scripts for better performance.

Related

Thread is passing same Request Body multiple times. JSR223 PreProcessor is used to generate random request body every time

My test has 2 API requests.
The parameters passed in 2nd API request body are to be unique every time. So I used JSR223 PreProcessor with groovy to generate that using RandomUtils.
The Thread group is set to have 3 threads with 15 sec Ramp up time and used Loop Controller with Loop count as 10. 1st API is in thread group and 2nd API is in Loop Controller as it needs to run multiple times.
But during test execution, for 2nd API one thread is passing same request body with same parameters multiple times. Because of which the test fails. How is that possible?
It's impossible to state "how is that possible" without seeing your Groovy code.
The most common mistake is using JMeter Functions or Variables in Groovy scripts. As per JSR223 Sampler documentation:
The JSR223 test elements have a feature (compilation) that can significantly increase performance. To benefit from this feature:
Use Script files instead of inlining them. This will make JMeter compile them if this feature is available on ScriptEngine and cache them.
Or Use Script Text and check Cache compiled script if available property.
When using this feature, ensure your script code does not use JMeter variables or JMeter function calls directly in script code as caching would only cache first replacement. Instead use script parameters.
If this is your case - refactor your code to use vars shorthand for JMeterVariables class instance instead of JMeter Functions or Variables syntax and it should resolve your issue.

How to run a JSR223 PreProcessor script once per loop

I currently have a loop that executes a bunch of queries via JDBC request samplers. They should all share a random ID that changes on every loop.
I tried using the beanshell script and JSR223 PreProcessor. But the PreProcessor gets executed before every single JDBC reuqest sampler, not once per loop. I feel like there is an obvious fix to my problem that I am missing.
I also tried putting the JSR223 script into an "Only Once Controller". But then the random variable I inject with vars.put() is not visible to the JDBC sampler. Also, as far as i understand the Only Once Controller, it would only execute on the first loop iteration. Which is not what I want.
JSR223 PreProcessor obeys JMeter Scoping Rules so if you put it to be a child of i.e. q_insert1 sampler - it will be executed only once per iteration.
I would also recommend re-considering language selection, since JMeter 3.1 it's recommended to use Groovy for scripting

How to execute a BeanShell PostProcessor after all samples end on Jmeter?

My goal is make a beautiful report about my test plan. I'm using about 50 threads and infinite loop so I want get the responses content and make the report. The problem is that the PostProcessor execute every sample request end so I can't put it all together on the same context to use all data and if I use the data every sample ends the results becomes a big mess. I don't found the solution on the web and I'm newbie with Jmeter. So, there are a way to wait all threads ends and get all responses data on 1x time ?
First of all don't use Beanshell, since JMeter 3.1 you should switch to JSR223 Test Elements and Groovy language
If you need to collect response data the best option is writing it into a file using i.e. Flexible File Writer and if any post-processing is needed you can perform this using JSR223 Sampler in the tearDown Thread Group

JMeter - How to make post processors reusable and use them on top of a test fragment on demand

Here is my scenario:
I created a test fragment for a sampler which is being used in many thread groups present in different jmx scripts. I sometimes would like to extract few values of this sampler result using few post processors.
Question:
How do I group and make these post processors reusable? I do not want to include as part of the test fragment itself as I don't need/want to execute post processor action every time.
Here is what I have tried:
I am able to save those post processors as a separate test fragment and include it in my test script right after the test fragment with the sampler whenever I want to execute them. I can save the sampler result to a jmeter variable and use it inside my post processor test fragment.
Is this a good approach? Please guide me.
Having Post-Procesors at the same level as all other Samplers is not a very good idea as they will be executed for each Sampler in their scope
Saving response data into a variable each time is also an overhead as according to your question you need the value sometimes
I would recommend using JSR223 Sampler to copy previous sampler response data and apply necessary Post-Processor(s) to it as child(ren).
The relevant code to copy the previous sampler response data would be as simple as:
SampleResult.setResponseData(ctx.getPreviousResult().getResponseData())
Where:
SampleResult - stands for current SampleResult
ctx - stands for JMeterContext
Check out Apache Groovy - Why and How You Should Use It article to learn more about Groovy scripting in JMeter conctept
The JSR223 Sampler can be saved as a Test Fragment as well.
Adding to #Dmitri T answer, in JSR PostProcessor you can save similar code in script file and reuse it
Script file A file containing the script to run, if a relative file path is used, then it will be relative to directory referenced by "user.dir" System property
Use the same script file in several post processors for re-usability:

jmeter - How to ignore selected samplers from getting measured in the *jtl file

My test configuration :
Loop Controller
--> Beanshell Sampler
vars.put("test", "${__CSVRead(*test,0)}");
Add it to an existing array retrieved from vars.getObject
In the above scenario, I am constructing my request payload dynamically in a loop controller. I had to put the CSVRead function in a separate Beanshell sampler under the loop controller since "${__CSVRead(*test,0)}" was reading the sample line if I use it within a for loop inside the beanshell sampler (interpreted mode).
While the above configuration meets my requirement, my *.jtl files are growing in size even for a 30 minute load test since the BeanShell sampler is getting measured all the time. While I am able to filter the required data by using the FilterResults tool, I want to know how to avoid this during the execution itself like the TestActionSampler
Use one of the following Test Elements instead:
BeanShell PreProcessor
BeanShell PostProcessor
Beanshell Timer
By default Timers and Pre/Post Processors execution time is not included into parent sampler elapsed time (unless you use Transaction Controller explicitly configured to do so), using this approach you will be able to exclude the time, required for constructing payload from test results.
I resolved it by using the following configuration.
Loop Controller
--> Test Action Sampler
--> Beanshell timer returning 0 at the end
vars.put("test", "${__CSVRead(*test,0)}");
Add it to an existing array retrieved from vars.getObject
return 0;

Resources