Home > database >  Extract objects in jmeter loop then query them in subsequent call
Extract objects in jmeter loop then query them in subsequent call

Time:06-20

Using Jmeter, I am running a script where I make a POST request, receive an object ID in the response, and then DELETE that object ID in a subsequent request. This works when using the JSON extractor and executing the script once, but I want to be able to do this with any number of loops through the script (i.e. successfully POST 40 times and then DELETE 40 times).

The most obvious solution seems to be to push each of those response objects to an array and then loop through, but I've had difficulty doing that- i.e., following enter image description here

  1. Then add your request and then you can add your Post Processor to extract a value from the response. Here I'm using a JSON Extractor. I'll be extracting a Property from the response body and adding it to a Jmeter property called RESPONSE_ID.

enter image description here

  1. Then after extracting the value from the body add a JSR223 PostProcessor and add the following script to it. Make sure you pass the extracted response parameter and the counter to the JSR223 PosrProcessor. Note the variable prefixes we are using below. For each iteration, we will be adding a new property.
// We need to add Props in the following format to Foreach to pick them
vars.put("loopId_"   vars.get("counter"), vars.get("RESPONSE_ID"))

The property has to be in the following format.

<NAME>_<INDEX> = <VALUE>

Following is what the script will look like with the loop controller.

enter image description here

  1. Next after the loop add another JSR223 PostProcessor. This is to set the Foreach iteration count. Add the following script.
//Set the foreach loop size
vars.put("loopId_matchNr", vars.get("counter"))

enter image description here

  1. Next add your Foreach Controller. Make sure you closely look at the naming conventions.

enter image description here

Adding extracted values to a List

Inorder to add to a list you have to initialize the list before your Loop Controller. You can add a JSR223 Sampler and initialize a list with the following code.

vars.putObject("outList", new ArrayList());
log.info("Initializing the list");

Then within the loop, you can add the entries to the list with the following code.

// Following is how the listcan be updated, we are not using this list
vars.getObject("outList").add(vars.get("RESPONSE_ID"));

After the loop, you can log the content with the following code.

log.info(vars.getObject("outList").toString());

The full JMX script is added below.

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3">
  <hashTree>
    <TestPlan gui test testname="Multiloop_iterator" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" gui test testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup gui test testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" gui test testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">1</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
        <boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
      </ThreadGroup>
      <hashTree>
        <JSR223Sampler gui test testname="Setting the List" enabled="true">
          <stringProp name="scriptLanguage">groovy</stringProp>
          <stringProp name="parameters"></stringProp>
          <stringProp name="filename"></stringProp>
          <stringProp name="cacheKey">false</stringProp>
          <stringProp name="script">vars.putObject(&quot;outList&quot;, new ArrayList());
log.info(&quot;Initializing the list&quot;);</stringProp>
        </JSR223Sampler>
        <hashTree/>
        <LoopController gui test testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">true</boolProp>
          <stringProp name="LoopController.loops">3</stringProp>
        </LoopController>
        <hashTree>
          <CounterConfig gui test testname="Counter" enabled="true">
            <stringProp name="CounterConfig.start">1</stringProp>
            <stringProp name="CounterConfig.end"></stringProp>
            <stringProp name="CounterConfig.incr">1</stringProp>
            <stringProp name="CounterConfig.name">counter</stringProp>
            <stringProp name="CounterConfig.format"></stringProp>
            <boolProp name="CounterConfig.per_user">false</boolProp>
          </CounterConfig>
          <hashTree/>
          <HTTPSamplerProxy gui test testname="HTTP POST" enabled="true">
            <elementProp name="HTTPsampler.Arguments" elementType="Arguments" gui test testname="User Defined Variables" enabled="true">
              <collectionProp name="Arguments.arguments"/>
            </elementProp>
            <stringProp name="HTTPSampler.domain"></stringProp>
            <stringProp name="HTTPSampler.port"></stringProp>
            <stringProp name="HTTPSampler.protocol"></stringProp>
            <stringProp name="HTTPSampler.contentEncoding"></stringProp>
            <stringProp name="HTTPSampler.path">http://demo5315474.mockable.io/post</stringProp>
            <stringProp name="HTTPSampler.method">POST</stringProp>
            <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
            <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
            <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
            <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
            <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
            <stringProp name="HTTPSampler.connect_timeout"></stringProp>
            <stringProp name="HTTPSampler.response_timeout"></stringProp>
          </HTTPSamplerProxy>
          <hashTree>
            <JSONPostProcessor gui test testname="JSON Extractor" enabled="true">
              <stringProp name="JSONPostProcessor.referenceNames">RESPONSE_ID</stringProp>
              <stringProp name="JSONPostProcessor.jsonPathExprs">$.ID</stringProp>
              <stringProp name="JSONPostProcessor.match_numbers"></stringProp>
            </JSONPostProcessor>
            <hashTree/>
            <JSR223PostProcessor gui test testname="JSR223 PostProcessor" enabled="true">
              <stringProp name="cacheKey">true</stringProp>
              <stringProp name="filename"></stringProp>
              <stringProp name="parameters">${RESPONSE_ID}, ${counter}</stringProp>
              <stringProp name="script">// We need to add Props in the following format to Foreach to pick them
vars.put(&quot;loopId_&quot;   vars.get(&quot;counter&quot;), vars.get(&quot;RESPONSE_ID&quot;))

// Following is how the listcan be updated, we are not using this list
vars.getObject(&quot;outList&quot;).add(vars.get(&quot;RESPONSE_ID&quot;));</stringProp>
              <stringProp name="scriptLanguage">groovy</stringProp>
            </JSR223PostProcessor>
            <hashTree/>
          </hashTree>
          <HTTPSamplerProxy gui test testname="HTTP DELETE" enabled="true">
            <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
            <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
              <collectionProp name="Arguments.arguments">
                <elementProp name="" elementType="HTTPArgument">
                  <boolProp name="HTTPArgument.always_encode">false</boolProp>
                  <stringProp name="Argument.value">{ &quot;dedlID&quot; : ${RESPONSE_ID} }</stringProp>
                  <stringProp name="Argument.metadata">=</stringProp>
                </elementProp>
              </collectionProp>
            </elementProp>
            <stringProp name="HTTPSampler.domain"></stringProp>
            <stringProp name="HTTPSampler.port"></stringProp>
            <stringProp name="HTTPSampler.protocol"></stringProp>
            <stringProp name="HTTPSampler.contentEncoding"></stringProp>
            <stringProp name="HTTPSampler.path">http://demo5315474.mockable.io/post</stringProp>
            <stringProp name="HTTPSampler.method">POST</stringProp>
            <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
            <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
            <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
            <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
            <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
            <stringProp name="HTTPSampler.connect_timeout"></stringProp>
            <stringProp name="HTTPSampler.response_timeout"></stringProp>
          </HTTPSamplerProxy>
          <hashTree>
            <HeaderManager gui test testname="HTTP Header Manager" enabled="true">
              <collectionProp name="HeaderManager.headers"/>
            </HeaderManager>
            <hashTree/>
          </hashTree>
        </hashTree>
        <JSR223Sampler gui test testname="Prepare Loop" enabled="true">
          <stringProp name="scriptLanguage">groovy</stringProp>
          <stringProp name="parameters"></stringProp>
          <stringProp name="filename"></stringProp>
          <stringProp name="cacheKey">false</stringProp>
          <stringProp name="script">//Set the foreach loop size
vars.put(&quot;loopId_matchNr&quot;, vars.get(&quot;counter&quot;))</stringProp>
        </JSR223Sampler>
        <hashTree/>
        <ForeachController gui test testname="ForEach Controller" enabled="true">
          <stringProp name="ForeachController.inputVal">loopId</stringProp>
          <stringProp name="ForeachController.returnVal">outVar</stringProp>
          <boolProp name="ForeachController.useSeparator">true</boolProp>
        </ForeachController>
        <hashTree>
          <HTTPSamplerProxy gui test testname="EachRequest" enabled="true">
            <elementProp name="HTTPsampler.Arguments" elementType="Arguments" gui test testname="User Defined Variables" enabled="true">
              <collectionProp name="Arguments.arguments"/>
            </elementProp>
            <stringProp name="HTTPSampler.domain"></stringProp>
            <stringProp name="HTTPSampler.port"></stringProp>
            <stringProp name="HTTPSampler.protocol"></stringProp>
            <stringProp name="HTTPSampler.contentEncoding"></stringProp>
            <stringProp name="HTTPSampler.path">https://localhost/${outVar}</stringProp>
            <stringProp name="HTTPSampler.method">GET</stringProp>
            <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
            <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
            <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
            <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
            <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
            <stringProp name="HTTPSampler.connect_timeout"></stringProp>
            <stringProp name="HTTPSampler.response_timeout"></stringProp>
          </HTTPSamplerProxy>
          <hashTree/>
        </hashTree>
        <ResultCollector gui test testname="View Results Tree" enabled="true">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value >
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>false</xml>
              <fieldNames>true</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <sentBytes>true</sentBytes>
              <url>true</url>
              <threadCounts>true</threadCounts>
              <idleTime>true</idleTime>
              <connectTime>true</connectTime>
            </value>
          </objProp>
          <stringProp name="filename"></stringProp>
        </ResultCollector>
        <hashTree/>
        <JSR223Sampler gui test testname="Logging the List" enabled="true">
          <stringProp name="scriptLanguage">groovy</stringProp>
          <stringProp name="parameters"></stringProp>
          <stringProp name="filename"></stringProp>
          <stringProp name="cacheKey">true</stringProp>
          <stringProp name="script">log.info(vars.getObject(&quot;outList&quot;).toString());</stringProp>
        </JSR223Sampler>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>
  • Related