You can embed arbitrary Java code directly into your JMeter tests using Groovy, which means you’re not limited by JMeter’s built-in samplers and logic controllers.
Let’s see this in action. Imagine you need to generate a unique identifier for each request, perhaps a UUID, or maybe you need to parse a complex JSON response and extract specific fields to use in subsequent requests. JMeter’s built-in capabilities might fall short here, but Groovy scripts can handle it seamlessly.
Here’s a simple JMeter setup demonstrating this. We’ll use a JSR223 Sampler (JSR223 stands for "Java Scripting API") to execute a Groovy script.
Test Plan
└── Thread Group
└── JSR223 Sampler
The JSR223 Sampler will have a "Script" area where you write your Groovy code. Let’s say we want to generate a timestamp and add it to a JMeter variable called myTimestamp.
// In the JSR223 Sampler's "Script" area
import java.time.Instant
// Get the current time in milliseconds since epoch
long currentTimeMillis = Instant.now().toEpochMilli()
// Store it in a JMeter variable
vars.put("myTimestamp", String.valueOf(currentTimeMillis))
// You can also print it to the JMeter logs for verification
log.info("Generated timestamp: " + currentTimeMillis)
When this sampler runs, JMeter executes this Groovy code. The vars object is a special JMeter object available in JSR223 elements, allowing you to read and write JMeter variables. vars.put("myTimestamp", ...) creates or updates a JMeter variable named myTimestamp with the generated timestamp.
Now, in a subsequent sampler (e.g., an HTTP Request), you can reference this variable:
Test Plan
└── Thread Group
├── JSR223 Sampler (generates myTimestamp)
└── HTTP Request (uses myTimestamp)
In the HTTP Request sampler, you could set a parameter or header like this:
Request Parameters:
Name: timestamp, Value: ${myTimestamp}
This allows you to dynamically alter your requests based on logic you define. You can also use ctx for context manipulation, sampler for sampler-specific actions, and prev to access the results of the previous sampler.
The real power comes from using Groovy to interact with external libraries, perform complex data transformations, or implement custom validation logic that JMeter’s GUI alone can’t provide. For example, you might fetch data from a database, process it, and then use that processed data to construct your request body.
// Example: Reading from a file and processing
def inputFile = new File("data/input.txt")
def lines = inputFile.readLines()
def processedData = []
for (line in lines) {
if (line.startsWith("user_")) {
processedData.add(line.substring(5).toUpperCase()) // Extract and uppercase
}
}
// Store the processed data in a JMeter variable for later use
vars.put("processedUsernames", processedData.join(","))
log.info("Processed usernames: " + processedData)
This script reads a file, iterates through its lines, filters and transforms them, and stores the result as a comma-separated string in a JMeter variable. This is incredibly useful for data-driven testing where your test data needs pre-processing.
The most surprising thing about using Groovy in JMeter is how it blurs the line between a load testing tool and a full-fledged scripting environment; you’re essentially writing miniature applications within your test plan to solve specific, often complex, data handling or business logic challenges that would be impossible to model with declarative configurations alone. You can even make HTTP requests directly from Groovy using libraries like HttpClient if you need to perform some setup or teardown actions that aren’t directly part of the user flow being simulated.
The next step is to explore using JSR223 PostProcessor to manipulate responses and JSR223 PreProcessor to prepare requests, leveraging the same Groovy scripting capabilities.