Wednesday, October 15, 2008

Jmeter UDV User Defined Variable Tips and Help

The first of many to come tips for others from what I've learned using JMeter.

JMeter has a convoluted way of dealing what most people would be familar with as 'variables'. JMeter has a controller called UDV - User Defined Variables where one can define a variable and assign it a value. But these seemed to have been tacked onto the product later, and their support is a bit messy.

The only real reference to variables in the documentation is here and it's pretty sparse. Here are some lessons learned

Lesson #1 - UDVs can not reference other variables in their own Controller. While you can create multiple variables in a single UDV controller, you can not reference a variable that is defined in that same controller. Example if you were to create two variables

tmsIP =
feedbackURL= ${tmsIP}/code.aspx

You can not define them both in the same UDV, you must create one UDV that defines tmsIP, and a second seperate UDV controller to define feedbackURL.

Lesson #2 - Beware the silent fail. If JMeter sees something it does not recognize, it just treats it like a string. So if you are trying to reference the variable 'Beta' using ${Beta} but fat finger it and type ${Betta} you will not get any errors from JMeter that the variable is unknown, etc. It will happliy pass the entire string ${Betta} along. This is the bane of your syntax world. The way to catch this is to use Debug samplers in your test plan along with View Results Tree. The Debug Sampler will show you the state of all the variables at that momment in the test, making it easier to see which do not appear right.

Lesson #3 - References to variable names (and functions too!) are all case sensative. When your variable does not get matched, it will be passed as the simple string and JMeter will not say a thing about it. be careful!

Lesson #4 - Variables are local only to it's own thread. Therefore they are unsuitable for sharing a common counter, etc between different threads in a thread group.

Lesson #5 - Where to manipulate values in an ongoing test. This is my biggest pet peeve of JMeter, there is no clear place to do simply data manipulation in its own step. For instance, for clarity purposes, you want a step that simply modifies an existing value. The answer is quite crude actually, you just put it anywhere! Including in comment fields! So if you want a step that does not generate any samples - you can create a test sampler, that does nothing for the actual test or result, but in the comment field you can put a function if you wanted. The net result of this is typically instead of organizing tests for readability where data manipulation may be seperate from actions using that data.. you end up putting most things 'inline' where the value is the result of a function using your variables or parameters and you do not save the result into its own variable.

Example, instead of defining another variable to hold the value, you may simply use a function like ${__jexl(${callDuration}*1000)} in the value field of a timer.

Lesson #6 - User Defined Variables are only processed at the start of a thread! This means any UDV elements can not be used to manipulate data as the test progresses. So you can't think of variables as you would in the traditional sense. Think of them as initial values that are local to the thread only. To get new values as the test progresses, you need to either use Properties, which can be modified as a test progresses, Parameters which can be redefined each time the element is hit, or use the result of functions to evaluate expressions that could contain your variables.

Lesson #7 - How to I manipulate/generate new values from variables in JMeter? Something simple like multiplying two values and storing the result? This is where the 'hands off' approach to data manipulation in JMeter is frustrating. Basically JMeter has almost no operator type functions... you need to dump all the work into JEXL, JavaScript, or BeanShell and reference it with the respective function. So if you don't know basic JEXL, JavaScript, or BeanShell, you gotta learn it to do basic stuff. Sucks. But basic operator stuff is pretty simple. Instead of assigning the result to a variable, typically it works best just to put the operation 'in line' where ever it is needed. So if my variable callDuration is in milliseconds and I need a seconds view of it, I could use ${__jexl(${callDuration}*1000)} which allows me to reference the JMeter variable callDuration and multiply it by 1000 and the expression's result will replace the function itself where ever it is located.

1 comment:

Andrew Maurer said...

Thanks much! Beating my head against the wall right now.