I've created a While Controller in Apache JMeter that I want to run for 10 minutes or until an exit condition is met. However the following function doesn't work.
${__jexl3(
("${start}" + 600000) > "${__time()}" || "${exit}"
)}
I'm new to JMeter. I may be misunderstanding how the JEXL evaluation works.
You need to remove quotation marks around the variables, otherwise __jexl3() function would be comparing Strings instead of Longs
${__jexl3(${start} + 600000 > ${__time(,)},)}
You can use i.e. Dummy Sampler in order to evaluate various parts of the expression and the whole expression. The results can be visualized via View Results Tree listener.
Related
The problem
My JMeter test calculates amount of threads that should be allocated to a thread group using JS expressions like this:
threadsGroupA expression: ${__javaScript(${__property(threads)}*${__property(threadPercentageA)})}
threadsGroupB expression: ${__javaScript(${__property(threads)}*${__property(threadPercentageB)})}
The properties passed to script:
threads=100
threadPercentageA=0.3
threadPercentageB=0.7
The expected result is: 30 threads assigned to group A and 70 threads assigned to group B.
This works as expected on my workstation. However, when I try to run it on a server, it does not create threads unless I use comma as a decimal separator in properties file:
threads=100
threadPercentageA=0,3
threadPercentageB=0,7
I am looking for a way to run the test with same property file in any environment.
What I tried
I have tried to force JVM to use locale with a decimal point . by adding -Duser.language=en -Duser.country=US -Duser.region=us (in different permutations) as variablesJMETER_OPTS, JMETER_LANGUAGE and also directly passed to JMeter as command line arguments(JMeter doc reference). None of that seemed to have any effect.
My thoughts
My conclusion at this point is that the problem is happening in JS engine that evaluates __javaScript()function. If there was a way to set locale for JS engine, I would be able to check this, hence the question in subject.
Use __groovy function and cast to integer/double the values before multiply:
${__groovy(props.get("threads").toInteger() * Double.parseDouble(props.get("threadPercentageB")),)}
Try using parseFloat() function for your decimal values like:
${__javaScript(${__property(threads)}*parseFloat(${__property(threadPercentageA))})}
If the output is decimal as well - in JavaScript there is Number.prototype.toLocaleString() function where you can explicitly set the locale for the Number object so you will have the confidence that it will return dot or comma no matter where it is run.
Also be aware that JavaScript engine is removed from the latest JDK/JRE versions so if you have a lot of JavaScript in your JMeter tests it makes sense to consider migrating to GraalVM or switching to __jexl3() or __groovy() functions
JS solution
Use parseFloat(), which always expects ., regardless of locale:
${__javaScript((${__property(threads)}*parseFloat("${__property(threadPercentageA)}")).toFixed())}
Credits for original idea to Dmitri T's answer
Groovy solution
${__groovy((props.get("threads").toInteger() * Double.parseDouble("${props.get('threadPercentageA')}")).round())}
Credits for original idea to user7294900's answer
Note about JMeter thread count handling
Turns out JMeter will not accept number of threads with decimal part, even if it is .0. Therefore, answers above include rounding functions.
How to put a condition using response assertion in jmeter.
In loadrunner we have web_reg_find with savecount attribute. This helps us to for keeping condition in IF loop.
if textcount >0
transaction --> pass
else
transaction--> fail and exit iteration and continue
Similarly, how to get the count of text check and place the same in condition (IF loop) in jmeter.
Use any of the post processor extractor to fetch all the values in a variable. Like in regular expression we can use "-1" in "match no." to fetch all the values matching with the regular expression. So, you will get the count.
Now, put that as a condition in if controller like ${__groovy("${countVar}"=="10")}
In short,
1.Add a Regular Expression Extractor as a child of the request to fetch all values.
2.Add If Controller at the same level to check the condition.
More information: 6 Tips for JMeter If Controller Usage
If you provide "Match No" as -1 in the Regular Expression Extractor
you will have ${foo_matchNr} variable containing the number of matches.
Since JMeter 4.0 you have __isVarDefined() function which can be used to check whether a JMeter Variable is defined or not
Both approaches can be used in the If Controller
I'm using jmeter and I would like to automate below scenario :
(In general I would like to increase value, I already know how to extract value from previous request)
Execute request_1
Extract value1 from request_1 using Regular expression extractor
Increment value1.
Put new value (increased) to the request_2
Any idea how can I achieve it ?
Check out __intSum() function, you can sum an arbitrary number of arbitrary integers via it.
Given you have a JMeter Variable called yourVar where the extracted value lives, the relevant __intSum() function configuration to increment ${yourVar} value by 1 will be something like:
${__intSum(${yourVar},1,yourVar)}
Demo:
If the value you're getting from the Regular Expression Extractor is more than 2 147 483 647 you will need to use __longSum() function instead.
See Apache JMeter Functions - An Introduction guide for more information on JMeter functions concept.
I have a while controller that waits for a certain regular expression to appear in the response before logging the user out. However, due to timeouts with the previous request this will occasionally enter into an infinite loop, skewing the data. I'm looking to set this request so that it only sends 5 times before exiting the loop and logging the user out.
After searching for an answer it seems that either the ${__counter()} variable or Counter Config Element are the solution, but neither seem to be working as I would expect.
Here is what I've got so far:
While Controller (${__javaScript( "${DONE_A}" != "Thank you for your order" || ${counter} < 5;)}
Counter (set to 5, increment 1)
Constant Timer (2000 ms)
GET /checkout/confirmation
^RegExp Extractor (DONE)
Logout
I can see a couple of problems with your script:
During 1st iteration counter value is NaN, you need to either declare it via i.e. User Defined Variables or to add check for "Not a Number" into your condition
You cannot refer variables as ${counter} in __JavaScript function. If you need to address it, you need to surround the variable with quotation marks (like you do for your DONE_A variable. If you need to treat the variable like a numeric one - use i.e. parseInt() function
Given point 2, my expectation is what your While controller clause simply does not work, that's why you're getting an endless loop.
This one should be good for your scenario:
${__javaScript(isNaN(parseInt("${counter}")) || parseInt("${counter}") < 5 && "${DONE_A}" != "Thank you for your order",)}
I was reading the JMeter documentation and came across this info box about "If Controllers":
No variables are made available to the script when the condition is interpreted as Javascript. If you need access to such variables, then select "Interpret Condition as Variable Expression?" and use a __javaScript() function call. You can then use the objects "vars", "log", "ctx" etc. in the script.
I don't quite follow this. Does this mean if I want access to a "User Defined Parameter" then I can access it only by writing some JavaScript? The example that follows this box then refers to "${COUNT}"
Could someone clarify the usage of the If Controller, maybe with an example or two?
All these answers are wrong! You need to put the variable reference in quotes, like so:
"${my_variable}"=="foo"
You can simply use something like
${my_variable}=='1'
Sometimes JMeter documentation can be confusing :)
Edit 27 september 2017:
The answer here works but has a very bad performance impact when number of threads exceeds 40.
See below for correct and most performing answer:
https://stackoverflow.com/a/46976447/460802
See:
https://bz.apache.org/bugzilla/show_bug.cgi?id=61675
UNCHECK the CHECKBOX
"Interpret condition as variable expression"
I wasted a couple of hours without unchecking this checkbox. It worked with and without semicolon(;) at the end of the statement. Make sure that you have set the User-Defined Variables before calling the if controller.
All the following variations worked for me in Jakarta Jmeter 1.5
${__javaScript("${HOMEPAGE}"=="Y")}
${__javaScript("${HOMEPAGE}"=="Y")};
"${HOMEPAGE}"=="Y"
"${HOMEPAGE}"=="Y";
If Controller will internally use javascript to evaluate the condition but this can have a performance penalty.
A better option (default one starting from JMeter 4, see https://bz.apache.org/bugzilla/show_bug.cgi?id=61675) is to check "Interpret Condition as Variable Expression?", then in the condition field you have 2 options:
Option 1 : Use a variable that contains true or false. For example If you want to test if last sample was successful, you can use
${JMeterThread.last_sample_ok}
or any variable you want that contains true/false
${myVar}
Option 2 : Use a function (${__jexl3()} is advised) to evaluate an expression that must return true or false.
For example if COUNT is equal to 1:
${__jexl3("${COUNT}"== "1",)}
OR
${__jexl3(${COUNT}== 1,)}
Starting with 4.0, if you don't use the "Interpret Condition as Variable Expression?", a warning in RED will be displayed:
If you'd like to learn more about JMeter and performance testing this book can help you.
God bless the http://habrahabr.ru
Have tried until found these.
Using the quotes was my solution.
As Gerrie said you need to check your variable
${my_var} == 'value'
But be careful with the 'User Defined Variables'
Note that all the UDV elements in a
test plan - no matter where they are -
are processed at the start.
That basically means that you cannot define 'User Defined Variables' inside an 'If Controller'. Take a look to the 'BeanShell' instead.
Replace:
${my_variable}=='1'
with
"${my_variable}" == "1"
if it's string value pass as below and its performance effective
${__groovy("${key}"=="value")}
I have used ${code_g1}== 200 in condition and it worked for me.