
When performing performance or load testing using Apache JMeter, you sometimes need to go beyond the built-in components to handle complex logic or dynamic behavior. This is where scripting becomes important. JSR223 is a feature in JMeter that allows you to write custom scripts using languages like Groovy, JavaScript, or Jython to enhance your test plans.
JSR223 provides a flexible and efficient way to add logic, manipulate variables, or interact with responses in a way that is not possible using standard JMeter elements.
It is especially popular for data extraction, request modification, dynamic input generation, and custom validations. Among the scripting options available in JMeter, JSR223 is considered one of the most powerful and fastest, especially when used with Groovy.
This article explores JSR223, how it works in JMeter, the different elements that support it, and why it is a better choice than older scripting options like BeanShell.
Why It’s called JSR223 element in JMeter? Let’s explore.
JSR223 stands for Java Specification Request 223. It is a Java standard that allows scripting languages like Groovy, JavaScript, Jython, and others to be used with Java applications. The name comes from the formal Java specification that defines how scripts can interact with Java code. In simple terms, JSR223 allows you to run scripts inside Java applications like JMeter.
Use in JMeter
In JMeter, JSR223 is used to run custom scripts to control or extend test behavior. This is useful when you need logic that is too complex for standard JMeter components. For example, if you want to calculate a custom value, extract specific information from a response, or change the flow of your test, you can write a JSR223 script to do it.
JMeter Elements Related to JSR223
JMeter has several elements that leverage JSR223 scripting:
JSR223 Element | Function |
---|---|
JSR223 Sampler | Executes scripts as independent sample requests |
JSR223 PreProcessor | Runs the script before the sampler executes |
JSR223 PostProcessor | Executes script after a sampler runs |
JSR223 Assertion | Validates sampler results using script-based logic |
JSR223 Timer | Introduces delays based on script logic |
Each of these elements lets you add script code written in a supported scripting language (like Groovy) to perform specific actions during test execution.
Use of Each JSR223 Element in JMeter
Here is a simple explanation of how each JSR223 element works:
1. JSR223 Sampler:
This element lets you write and run a script as a sampler (like making a request). You can use it to send custom data, call an API manually, or simulate some logic that doesn’t rely on HTTP or JDBC samplers.
Use: Generate dynamic test data, reading a file, or making calculations.
Example: To simulate a custom HTTP GET request (without using the built-in HTTP Request sampler), and log the response. This is useful when you want full control over request construction and handling.
import org.apache.jmeter.samplers.SampleResult
import java.net.HttpURLConnection
import java.net.URL
// Create a SampleResult to track timing and results
SampleResult sampleResult = new SampleResult()
sampleResult.sampleLabel = "Custom GET Request via JSR223"
// Start timing
sampleResult.sampleStart()
try {
// Define the URL to request (can use JMeter variables here)
def urlString = "https://httpbin.org/get"
URL url = new URL(urlString)
HttpURLConnection connection = (HttpURLConnection) url.openConnection()
connection.setRequestMethod("GET")
// Read the response
def responseText = connection.inputStream.text
// Mark the sample as successful
sampleResult.responseData = responseText.getBytes("UTF-8")
sampleResult.dataType = SampleResult.TEXT
sampleResult.successful = true
sampleResult.responseCode = connection.responseCode.toString()
sampleResult.responseMessage = "OK"
} catch (Exception e) {
// In case of error, capture the exception
sampleResult.successful = false
sampleResult.responseMessage = "Exception: " + e.getMessage()
sampleResult.responseCode = "500"
} finally {
// Stop timing
sampleResult.sampleEnd()
// Set the result to the JMeter context
SampleResult.setSampleResult(sampleResult)
}
2. JSR223 PreProcessor:
This runs before the main sampler. You can use it to set up variables, prepare data, or modify request parameters before sending.
Use: Extract part of a URL, create a timestamp, or set headers.
Example: To generate a unique username using a prefix and a random number
def randomNumber = new Random().nextInt(100000) // Generates number from 0 to 99999
def uniqueUsername = "user" + randomNumber
// Save it as a JMeter variable to be used in the next sampler
vars.put("dynamicUsername", uniqueUsername)
3. JSR223 PostProcessor:
This runs after a sampler. You can use it to extract, analyze, or modify the response data, such as parsing JSON/XML to store in variables
Use: Parse the response to get a token or extract a value using JSON or regex, writing the content to a file.
Example: To write the value of a variable to a file.
// Name of the JMeter variable captured earlier (e.g., from JSON Extractor or Regex Extractor)
def orderIDValue = vars.get("orderID") // Replace with your actual variable name
// Define the file path - use absolute path or JMeter's ${__dir} for relative
def filePath = "C:/jmeter_output/response_values.txt" // Change path as needed
// Open the file in append mode and write the value
def file = new File(filePath)
file << orderIDValue + System.lineSeparator()
4. JSR223 Assertion:
This is used to write custom logic to assert specific conditions on the response, such as status codes or content values. If the condition fails, the test will be marked as failed.
Use: Check if a response contains a specific value or matches a pattern.
Example: To validate that an orderId returned in the HTTP response starts with “IND” (e.g., “IND20240623”). If it doesn’t, the assertion should fail with a helpful message.
import groovy.json.JsonSlurper
// Parse the response body as JSON
def response = prev.getResponseDataAsString()
def json = new JsonSlurper().parseText(response)
// Extract the orderId from the response
def orderId = json.orderId // Assumes response is like {"orderId":"IND12345"}
// Perform the assertion: check if orderId starts with "IND"
if (orderId == null || !orderId.startsWith("IND")) {
AssertionResult.setFailure(true)
AssertionResult.setFailureMessage("Assertion Failed: orderId is missing or does not start with 'IND'. Found: ${orderId}")
}
5. JSR223 Timer:
This element is used to delay execution using custom logic.
Use: Add a delay based on a random value or based on a condition.
Example:
// Generate a random delay between 1000 ms (1 sec) and 5000 ms (5 sec)
def minDelay = 1000 // minimum delay in milliseconds
def maxDelay = 5000 // maximum delay in milliseconds
def delay = minDelay + (Math.random() * (maxDelay - minDelay)) as int
// Return the delay value to JMeter (in milliseconds)
return delay
// Optional: Log the actual delay time (helpful for debugging)
log.info("JSR223 Timer applied a delay of ${delay} ms")
How is it better than BeanShell Scripting?
Before JSR223, many testers used BeanShell, another scripting option in JMeter. However, JSR223 is now preferred for several reasons:
- Performance: JSR223 with Groovy is much faster than BeanShell. BeanShell scripts require interpretation every time, slowing down tests.
- Better Memory Usage: It uses less memory and is more efficient.
- Thread Safety: JSR223 with Groovy supports compilation and caching, minimizing memory issues and ensuring better thread handling.
- Stable and Updated: JSR223 is more modern and stable than BeanShell, which is older and not actively developed.
- Java Compatibility: Groovy has near-native integration with Java APIs and avoids quirky behavior that sometimes occurs in BeanShell.
- Precompiled Scripts: Groovy scripts in JSR223 can be compiled, making them run faster.
- More Language Options: JSR223 supports multiple languages, although Groovy is the most commonly used.
- Ease of Maintenance: Groovy code tends to be more readable, concise, and powerful than BeanShell equivalents.
Conclusion
JSR223 scripting in Apache JMeter is a powerful tool for adding custom behavior and logic to your performance tests. It provides better speed, flexibility, and modern scripting compared to older methods like BeanShell. By using JSR223 elements like samplers, pre/post-processors, and assertions, you can make your tests more dynamic and efficient. If you’re just getting started with JMeter scripting, learning Groovy with JSR223 is a great place to begin.
You may be interested: