I have a test plan in jMeter that requires some parameters that needs to be calculated before running the test. In order to calculate these parameters, I created a JSR223 PreProcessor directly under test plan as seen below.
My problem is PreProcessor seems to run before every request which is not what I want. I need to calculate these parameters only once and use them in testing.
Is there a way to run the JSR223 PreProcessor only once, or should I use another method?
Thanks in advance.
Edit:
As #ubik-load-pack suggested, I tried "setUp Thread Group" as following but variables created in the code was not available under "Thread Group". They were also present neither in the logs (logging is used in the code) nor in the View Results Tree (via Debug PostProcessor)
I also tried "Once Only Controller" which also didn't work, same as above.
For more information here is content of my JSR223 PreProcessor. (Not the whole code, there will be more variables here so using date functions is not a solution for me by the way.)
By design a PreProcessor runs before any Sampler runs.
So if you want to run something only once per user, you can do the following:
Use a Once Only Controller and put in it a JSR223 Sampler that will contain your code.
If you want to do it once for all users, then use a setupThreadGroup
that will contain your JSR223 Sampler and configure it with 1 thread. It will run once before the regular Thread Groups are started.
EDIT after you updated your question:
As I wrote, you cannot use the setupThreadGroup approach if you want to reuse variables in Thread Groups so stick to OnceOnlyController approach for your request
With the Once Only Controller it is not working because you misread my answer, I am suggesting to use a JSR223 Sampler not PreProcessor as a preprocessor will run only if there is a sampler that runs.
If you use a Sampler, and you have multiple ThreadGroups, then you'll have to copy that sampler into each ThreadGroup, since you can't put Samplers outside of ThreadGroups.
you can use jsr223 PreProcessor with:
if(vars.get("init")=="OK") return;
vars.put("init","OK")
//your code
I'm doing a slightly dirty workaround at the top of the preprocessor:
log.info("in PreProcessor. Sampler name: " + sampler.getName())
if (sampler.getName() != "HTTP Request") {
log.info("not running again")
return
}
In my case I cannot add another sampler because it will mess up my timer calculations.
Related
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
I'm new to Jmeter and vigorously learning.
I wanted to know how JSR223 Sampler and JSR223 PreProcessor are different, can a sampler be used the same way as the preprocessor?
General difference is that PreProcessor won't be executed unless it has a sampler in its scope which it will be triggered (per sampler)
Pre-Processor element is defined to alter the settings of Samplers in their scope. It will always execute before the actual sampler request.
Specific difference is that JSR223 PreProcessor doesn't have SampleResult available, so for example you can't execute the following example:
SampleResult.setStopTest(true);
The SampleResult ResponseData is set from the return value of the script. If the script returns null, it can set the response directly, by using the method SampleResult.setResponseData(data), where data is either a String or a byte array. The data type defaults to "text", but can be set to binary by using the method SampleResult.setDataType(SampleResult.BINARY).
The SampleResult variable gives the script full access to all the fields and methods in the SampleResult. For example, the script has access to the methods setStopThread(boolean) and setStopTest(boolean).
JSR223 Sampler is a Sampler, so it will generate a SampleResult which will appear in the Test Results (unless you call SampleResult.setIgnore() method)
JSR223 PreProcessor cannot be executed per se, you need to connect it to one (or many) Samplers according to JMeter Scoping Rules so it will be executed before one (or many) samplers. PreProcessors execution time is not reflected in the test results (unless you use a Transaction Controller configured to include it)
Both can run an arbitrary code (it's recommended to stick to Groovy) so which one is to use mostly depends on your use case, if you need to conduct the load and measure the time - go for the Sampler, if you need to set up some data - go for the PreProcessor, etc.
I want to run code at the beginning that sets up variables, but as far as I can tell, the options for running code are:
Sampler: Appears in JMeter reports and screws up my numbers.
Pre-processor/Post-processor/Assertion: Must be attached to existing sampler.
Timer: This works sometimes, but it appears that if you have your timers higher in the tree than your samplers, they just get ignored.
Listener: Runs after your samplers (I want this code to run before everything else).
Is there a way to run code without modifying reports or attaching it to a sampler?
Add Test Action sampler to the place in the Test Plan where you want to run your code
Add JSR223 PreProcessor as a child of the Test Action sampler
Tick Cache compiled script if available box
Put your code into Script area
This is something you're looking for as
Test Action sampler will not be reflected in the load report:
Each sampler (except Test Action) generates one or more sample results.
Currently Groovy is the best scripting option available in JMeter
See Execution order:
Configuration elements
Pre-Processors
Timers
Sampler ...
For example of Configuration element
The User Defined Variables Configuration element is different. It is processed at the start of a test, no matter where it is placed.
Inside it you can execute JMeter functions which include numerous options as to read from CSV, execute groovy or beanshell code...
You can add your action as a Sampler (no matter JSR223 or anything else) and then add a PostProcessor that will mark this Sampler's result as ignored. It can be done with JSR223 PostProcess with groovy script:
prev.setIgnore()
You can also control whether or not to ignore this sample based on the conditions.
I want that some beanshell samplers of my testplan should not be shown in view results tree. Is that somehow possible?
Best regards,
Peter
In your case, you can add the below line directly to your script:
SampleResult.setIgnore();
Then your BeanShell samplers won't show in the view results tree.
Also, for any controller you can add a child JSR223 PostProcessor under it and add the following script:
prev.setIgnore();
No, It is not possible.
If I want to hide the sampler, I will try to see If I could use Beanshell preprocessor or Beanshell post processor instead of Beanshell sampler.
Beanshell preprocessor should be used instead of beanshell sampler.
It doesn't appear in the result tree.
AFAIK the only way is to disable them. Then they do not execute and therefore are not shown in the results.
I agree that a pre or post processor is the best solution, but not always viable.
In my case my test plan runs 1 of about 20 random tests each iteration. Putting a pre or post action on each of these is technically possible, but creates a significant maintenance overhead. The SampleResult.setIgnore(); solution worked in this case as I only had a single sampler to ignore.
I have a JMeter script running for x number of users. I want to conditionally close a user thread in a while controller. For example, if my while controller exits for a user thread, I need to stop the thread. Is it possible? Sorry if this is duplicate or a dumb question.
There are at least 2 options on how you can conditionally stop test thread or even the whole test:
Use Test Action sampler in combination with If Controller
Use Beanshell Sampler or PostProcessor and invoke setStopThread method of SampleResult class. See How to use BeanShell guide for example. For reference:
if (condition){
SampleResult.setStopThread(true); // for Beanshell Sampler
prev.setStopThread(true); // for Beanshell Post Processor
}
ctx.getThread().stop() sets the "stop" flag in the current thread, it works anywhere the JMeterContext ctx is exposed.
I have just done and verified it in a complex test script.