Jan. 30th, 2017

Apache Groovy - Why and How You Should Use It

Groovy is the New Black

 

JMeter is a very powerful tool. Out of the box, there are enough Test Elements to implement almost any test scenario, even a sophisticated one. However, certain use cases cannot be covered by using default JMeter test elements and functions alone. Therefore, scripting with JMeter and Java API methods may be required to bypass the limitations. This leads to the following question: which scripting language to use?

 

groovy scripting language

 

Starting from JMeter version 3.1, Groovy became the default scripting language for JSR223 Elements. This change has a history. While JSR223 elements have always had Groovy support (as well as any other scripting engine, given the relevant library is in the JMeter’s Classpath), groovy-all.jar became a part of the default JMeter bundle only in the JMeter version 3.0).

 

Prior to that JMeter users had to download the Groovy library manually and include it in the JMeter classpath. This caused some problems in using 3rd-party plugins, scaling out JMeter tests when new JMeter instances had to be created on-the-fly and added an extra step when performing an upgrade to a newer JMeter version. Now, all of these problems are gone and Groovy is the only recommended scripting language.

 

Why Groovy?

 

Apache Groovy is a dynamic object-oriented programming language that can be used as a scripting language for the Java platform. The most prominent features are:

- Development and support: Groovy language is being constantly developed, maintained and supported

- Java compatibility: valid Java code in 99% of cases will be valid Groovy code

- Performance: starting from version 2, Groovy scripts can be statically compiled providing near Java code performance

- Additional features on top of Java that make code more readable and compact, like native support of regular expressions, XML, JSON, simplified work with files and much more


Groovy is more “modern” language

 

When I state “valid Java code in 99% of cases will be valid Groovy code” it means that code that is developed using Java 6, 7 or 8 will be treated as a valid Groovy code. If you are using Beanshell, for example, you are limited to Java 5 language level, which means:

- No binary literals

- No strings in “switch” statements

- No Generics (“diamond” syntax is not supported)

- No try-with-resources

- No multiple exceptions handling

 

Groovy performance

 

Let’s compare the performance of Groovy scripts with Beanshell equivalents by starting with something very basic, for example printing JMeter test start time (the relevant JMeter variable is TESTSTART.MS to jmeter.log file.

 

log.info(vars.get("TESTSTART.MS"));

 

compare the performance of Groovy scripts with Beanshell equivalents

 

At first glance, Beanshell is faster (1 ms response time for Beanshell Sampler versus 5 ms response time for JSR223 Sampler). This is due to Groovy scripting engine size. As groovy-all-2.4.7.jar library size is almost 7 megabytes, it takes more time to load it. So if you use scripting for something very “light” and something which is being called once - it is still fine to use Beanshell.

 

Now let’s try something “heavier”, for instance calculating 36th number of Fibonacci sequence and again printing it to jmeter.log file using Beanshell and Groovy.

 

int fibonacci(int i) {
   if (i == 1 || i == 2) {
       return i;
   }
   return fibonacci(i - 1) + fibonacci(i - 2);
}

log.info("Fibonacci number 36: " + fibonacci(36));

 

The above code is used in both the Beanshell and JSR223 Samplers.

 

compare the performance of Groovy scripts with Beanshell equivalents

 

As far as you can see, the JSR223 Sampler calculates and prints the number out in 192 milliseconds, while the Beanshell Sampler needs over 36 seconds to do the same. So if you use scripting for generating the main load or the scripting sampler is called multiple times with multiple threads, the choice is obvious - go for Groovy.

 

Groovy “syntax sugar”

 

Groovy provides native syntax for some use cases that you might find useful for simplifying everyday life tasks.

 

Writing to and reading from files

 

Assuming you have initialized a File object, you can write to it as simple as this:

 

myFile << "Hello from Groovy"

 

Reading the file in its turn is just accessing the .text property of the File object:

 

 def fileContent = myFile.text

 

Putting everything together:

 

groovy, Writing to and reading from files

 

Iterating collections

 

Working with collections in Groovy is also very quick and easy. For example, here is the code that prints all the JMeter Properties names along with values to jmeter.log file:

 

props.each { k, v -> log.info( "${k}:${v}") }

 

Here is the output:

 

groovy, iterating collections

 

Executing external commands

 

With Groovy you can forget about the OS Process Sampler. Running OS commands or other executables is just this:

 

"your_command".execute()

 

If you need the output - just append .text property to the end:

 

"your_command".execute().text

 

Here is an example of executing the jmeter -v command and printing the output to the jmeter.log file:

 

Here is an example of executing the jmeter -v command and printing the output to the jmeter.log file

 

__groovy() function

 

The brand new __groovy() function is available since JMeter 3.1 and it allows evaluating arbitrary Groovy code anywhere in the script where functions can be placed.

 

The brand new __groovy() function is available since JMeter 3.1 and it allows evaluating arbitrary Groovy code anywhere in the script where functions can be placed.

 

Assuming all the above and given that Groovy is now a part of JMeter distribution, I would recommend everyone start using it for scripting and eventually migrate the scripting logic developed in other scripting languages, to Groovy. As usual you are welcome to use the below discussion form for any queries or feedback.

Interested in writing for our Blog? Send us a pitch!