user3920295
user3920295

Reputation: 909

JMeter - fail a test based on the average response time

I am running a JMeter job in Jenkins using performance plugin. I need to fail a job if the average response time < 3 seconds. I see the "duration assertion" in jmeter, but that works on each thread (each http request). Instead is it possible to do the duration assertion on average for each page?

This is the way I tried adding the BeanSehll Listener and Assertion.

Recording Controller
       **Home Page**
         BeanShell Listener
         Debug Sampler
       **Page1**
         BeanShell Listener
         Debug Sampler
Beanshell Assertion
View Results Tree       

Upvotes: 3

Views: 4014

Answers (2)

Geerten
Geerten

Reputation: 1057

Based on the other answer, I managed to create something that works while using multiple threads.

Add the following code as a script to your JSR223 listener, you can also save it to file and load it from file (for easy reuse). I used a parameter in seconds to set the duration threshold.

import org.apache.jmeter.util.JMeterUtils;

int totalRequests = Integer.parseInt(ctx.getThreadGroup().getSamplerController().getProperty("LoopController.loops").getStringValue()) * ctx.getThreadGroup().getNumThreads();
long requestsCount = JMeterUtils.getPropDefault("requestsCount"+sampleResult.toString(),0);
long timesSum = JMeterUtils.getPropDefault("times"+sampleResult.toString(),0);

long thisRequestTime = sampleResult.getTime();
timesSum += thisRequestTime;
requestsCount++;

JMeterUtils.setProperty("requestsCount"+sampleResult.toString(), String.valueOf(requestsCount));
JMeterUtils.setProperty("times"+sampleResult.toString(), String.valueOf(timesSum));

long average = timesSum / requestsCount;

long threshold = Integer.parseInt(args[0])*1000;
if (requestsCount >= totalRequests) {
    if(average > threshold){
        sampleResult.setSuccessful(false);
        sampleResult.setResponseMessage("Average response time is greater than threshold, average: " + String.valueOf(average) + ", threshold: " + threshold);
    }
    log.info("Average response time (" + sampleResult.toString() + "): " + String.valueOf(average) + ", threshold: " + threshold);
}

This stores it in the global properties, that are saved for the full JVM run. To keep consistency in between runs, I added a setup thread group with a JSR223 sampler, with this code:

import org.apache.jmeter.util.JMeterUtils;
JMeterUtils.getJMeterProperties().clear();
log.info("cleared properties");

Upvotes: 0

Dmitri T
Dmitri T

Reputation: 168197

You can implement this check via some form of Beanshell scripting

  1. Add a Beanshell Listener at the same level as all your requests live
  2. Put the following code into Beanshell Listener's "Script" area

    String requests = vars.get("requests");
    String times = vars.get("times");
    long requestsSum = 0;
    long timesSum = 0;
    
    if (requests != null && times != null) {
        log.info("requests: " + requests);
        requestsSum = Long.parseLong(vars.get("requests"));
        timesSum = Long.parseLong(vars.get("times"));
    }
    
    long thisRequest = sampleResult.getTime();
    timesSum += thisRequest;
    requestsSum++;
    
    vars.put("requests", String.valueOf(requestsSum));
    vars.put("times", String.valueOf(timesSum));
    
    
    long average = timesSum / requestsSum;
    
    if (average > 3000){
        sampleResult.setSuccessful(false);
        sampleResult.setResponseMessage("Average response time is greater than threshold");
    }
    

    The code above will record sums of response times for each request and total number of requests into times and requests JMeter Variables

See How to use BeanShell: JMeter's favorite built-in component guide for comprehensive information on Beanshell scripting in Apache JMeter.

Upvotes: 3

Related Questions