Mathematical Functions and Converting Data Types in Groovy
Mathematical Functions
A function is the dependence of one variable on another, or, in simple terms, a function is a definite action on a variable. For example, we take the variable X, perform a certain action with it (for example, exponentiation) and get the variable Y.
In performance testing, mathematical functions are widely used in cases when the logic of the tested object contains mathematical calculations. In this case, testers must perform the mathematical calculations themselves in Apache JMeter™, and then compare them with the result that the tested object returns.
Suppose we have an API that takes two numeric values, multiplies those values, and returns the result to the user. We need to test the correctness of the multiplication operation that the API performs.
When creating the test, two classes will be used:
- Math from the java.lang package
- Precision from org.apache.commons.math3.util
These classes contain various methods that correspond to mathematical functions and can be used in testing.
In our test, we will create input values for the API in a random way. In addition, numeric values and the result that the API returns can contain a fractional part with three characters (for example, 4.222 x 1.222 = 5.159).
In order to create a test using the methods from these classes, you need to do the following in JMeter:
1. Add a Thread Group
Right Click -> Add -> Threads(Users) -> Thread Group
2. Add a JSR223 Sampler
Thread Group -> Right Click -> Add -> Sampler -> JSR223 Sampler
JSR223 Sampler -> Language Groovy
In this step, we will create input data for the API and perform a multiplication operation. Then, we will compare our multiplication result to the result that the API returns.
In the JSR223 Sampler, add the following code example.
import org.apache.commons.math3.util.Precision; double a; a = Math.random(); double b; b = Math.random(); log.info(a + ""); log.info(b + ""); a = Precision.round(a,3); b = Precision.round(b,3); log.info(a + ""); log.info(b + ""); double res = a * b; res = Precision.round(res,3); log.info(res + "");
This code does the following:
import org.apache.commons.math3.util.Precision - This is the import of class that is necessary for writing code. The class data is imported from the Jar file we added to JMeter.
double a & double b - these are variables that are created randomly and will be passed to the API request.
a = Math.random(); b = Math.random(); - the method for generating a random number that is greater than or equal to 0 and less than 1. In our case, this method will always generate a number without the integer part (for example, 0.6366686760282807)
Precision.round(a,3); - A method that performs number rounding. The number 3, indicated in the method, means the number of characters after the floating point. In our case, the Precision.round (a, 3) method rounds the variable a to 3 characters (e.g 0.324).
log.info(res + ""); - A method that outputs data to the console. In our case, this method outputs the value of “res” to the console.
The code shown above can be written more concisely, as shown below
import org.apache.commons.math3.util.Precision; double a = Precision.round(Math.random(),3); double b = Precision.round(Math.random(),3); double res = Precision.round(a * b, 3); log.info(res + "");
Now that the variables are created and their calculation result is executed, it remains for us to pass the variables "a" and "b" to the API request and perform a comparison of our calculation with the result that the API returns.
In the code example above, we created the variables "a" and "b", for which the integer part is "0". In order to create variables with an integer part that is not equal to "0", we need to do the following:
In the JSR223 Sampler, add the following code example.
import org.apache.commons.math3.util.Precision; double a = Precision.round(Math.random() * 10,3); double b = Precision.round(Math.random() * 10,3); double res = Precision.round(a * b, 3); log.info(a + ""); log.info(b + ""); log.info(res + "");
This code sample differs from the previous one only in that after the Math.random () method creates a random value, we multiply it by 10. As a result of multiplication, we get variables for which the integer part is not equal to "0".
Below are the methods that are most commonly used when creating automated tests in JMeter:
int a = Math.abs(-23); log.info("Method abs: " + a); int b = Math.max(12, 9); log.info("Method max: " + b); int c = Math.min(12, 9); log.info("Method min: " + c); int d = Math.pow(3, 2); log.info("Method pow: " + d); int e = Math.round(12.55); log.info("Method round: " + e); int f = Math.sqrt(16); log.info("Method sqrt: " + f);
Math.abs (-23); - A method that returns the absolute value of an argument. An argument is a value that is passed to the method. In our case, the argument is -23.
Math.max (12, 9); Returns the maximum argument of two arguments
Math.min (12, 9); - Returns the minimum argument of two arguments
Math.pow (3, 2) - The method of exponentiation. In our case, the number 3 is raised to the power of 2.
Math.sqrt (16) - Extracts the square root of the argument
The Math class also contains methods for calculating trigonometric and logarithmic functions.
Converting Numeric Data Types
The conversion of numeric data types means changing one type of data to another. A data conversion can be of automatic or explicit type, and it can be performed with loss of accuracy or without loss of accuracy.
Automatic Data Type Conversion
An example of when you would need automatic conversion, is when performing arithmetic operations on variables of different types.
When automatically converting numeric data types, follow these rules:
- If the expression uses variables with the data type byte, short, and char, then these variables are converted to int. The result of the expression will also be of type int.
- If the expression uses a variable with data type long, then all variables are converted to long. The result of the expression will also be of type long.
- If the expression uses a variable with the data type float, then all variables are converted to the float type. The result of the expression will also be of type float.
- If the expression uses a variable with data type double, then all variables are converted to double. The result of the expression will also be of type double.
To perform automatic type conversion, you need to do the following
1. Add a Thread group
2. Add a JSR223 Sampler
Thread Group -> Right Click -> Add -> Sampler -> JSR223 Sampler
JSR223 Sampler -> Language Groovy
In the JSR223 Sampler, add the following code example.
short a = 12; byte b = 3; long c = 10; float e = 5.25; double d = 10.5555555; int res = a + b; log.info("Conversion to int type: " + res); long res1 = a + b + c; log.info("Conversion to long type: " + res1); float res2 = a + b + c + e; log.info("Conversion to float type: " + res2); double res3 = a + b + c + e + d; log.info("Conversion to double type: " + res3);
Explicit Data Type Conversion
An explicit conversion occurs when the result of calculation an expression is one data type, and we want to convert it to another type. To perform an explicit conversion of a data type, we must specify the data type before the expression explicitly, for example (long) (a + b + c). As a result of calculation expression, we get the result with the data type long.
To perform an explicit type conversion, you must do the following:
1. Add a Thread group
2. Add a JSR223 Sampler
Thread Group -> Right Click -> Add -> Sampler -> JSR223 Sampler
JSR223 Sampler -> Language Groovy
In the JSR223 Sampler, add the following code example.
short a = 12; byte b = 3; int c = 10; long res = (long) a + b + c; log.info("Conversion to long type: " + res);
Maintaining and Losing Accuracy when Converting
Automatic and explicit conversion can lead to loss of accuracy, as shown below.
int a = 123456789; float b = a; log.info("a: " + a); log.info("b: " + b);
The image above shows that after converting the data type int a = 123456789 to float, we get a different number. This is called loss of accuracy.
Variable b has the same order, but with less accuracy.
- a = 123456789
- b = 123456792 (1.23456792E8)
Here is a list of conversions with loss and without loss of accuracy:
Data type conversions without loss of accuracy:
- byte to short
- short to int
- char to int
- int to long
- int to double
- float to double
Data type conversions with loss of accuracy:
- int to float
- long to double
- long to float
If we want to convert a data type with a floating point (double) to an integer type (int), then the fractional part will be ignored (the rounding operation will not be performed). An example of such a conversion is shown below.
In the image above, we see that as a result of conversion double to int, the fractional part was discarded (the rounding operation is not performed).
Given the material in this article, you can significantly reduce the number of errors allowed in the development of tests that contain mathematical calculations with different types of data.
Learn more about what you can do in your performance tests with JMeter by taking our free JMeter Academy courses.
You can also enhance your load tests by using BlazeMeter. Here’s how:
- Simple Scalability – It’s easy to create large-scale JMeter tests. You can run far larger loads far more easily with BlazeMeter than you could with an in-house lab.
- Rapid-Start Deployment – BlazeMeter’s recorder helps you get started with JMeter right away, and BlazeMeter also provides complete tutorials and tips.
- Web-Based Interactive Reports – You can easily share results across distributed teams and overcome the limitations of JMeter’s standalone UI.
- Built-In Intelligence – The BlazeMeter Cloud provides on-demand geographic distribution of load generation, including built-in CDN-aware testing.
To try us out, request a demo, or put your URL in the box below, and your test will start in minutes.