Search code examples
javajmeterbeanshell

JMeter - Variable set in preprocessor is not available to sampler


I have a relatively simple JMeter test plan setup as shown here: https://i.sstatic.net/TYsq3.jpg

The relevant part of this is the BeanShell Preprocessor (shown as Setup element data) and its relationship to the HTTP Request sampler (shown as POST /elements). Both of these are inside a Loop Controller (shown as Do a few times).

The Preprocessor gets an array of data stored on the bsh.shared object and randomly selects one item. It then sets a variable called elementTypeId.

When I run this test, elementTypeId gets logged (and I therefore assume is set) correctly. However, the first time around, the variable is not set correctly and still appears as ${elementTypeId}. Further samples appear to be set but use the n-1th value.

The first, failing sample is shown here: https://i.sstatic.net/kkvvw.jpg

The final sample (and logged values) are shown here: https://i.sstatic.net/jDwhe.jpg

Setup element data - BeanShell Preprocessor code:

import java.util.Random;
import com.eclipsesource.json.*;

Random rand = new Random();
int idx = rand.nextInt(bsh.shared.elementTypes.size());

JsonValue elementType = bsh.shared.elementTypes.get(idx);
String elementTypeId = String.valueOf(elementType.get("id").asInt());
log.info(elementTypeId);
vars.put("elementTypeId", elementTypeId);

It looks to me as if the sampler is firing before the preprocessor has set the variable - which seems counter to what should be happening.

Update following UBIK's answer

When I disable the SetQueryParams PreProcessor, it appears that the variable is set correctly (although the request fails as it needs a query parameter to be added).

SetQueryParams PreProcessor:

import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;

if (sampler instanceof HTTPSamplerBase && 
sampler.getMethod().equalsIgnoreCase("post")) {
    // add query parameter to url
    var customPath = sampler.getPath() + '?' + sampler.getQueryString();
    sampler.setPath(customPath);

    // remove query parameter from body
    arguments = sampler.getArguments();
    while (arguments.getArgumentCount() > 1) {
        arguments.removeArgument(arguments.getArgumentCount() - 1);
    }
    sampler.setArguments(arguments);
}

Is it possible to have both preprocessors applied to the POST request?


Solution

  • I think you issue might be coming from the other PreProcessor :

    • SetQueryParams PreProcessor

    As per scoping rules , this one runs for every HTTP Sampler.