Bernie Lenz
Bernie Lenz

Reputation: 2146

JMeter JSON Path Extractor with input variable

Is it possible to use input variables in the JSON Path Extractor expression?

I tried expression $.[${someInputVariable}].name, but it didn't work.

Data format:

[ 
{name=a}, 
{name=b}, 
{name=c}
]

If for example ${inputVariable} is set to 1, I would like the expression to return "b".

All the examples I found so far have hardcoded search values such as $.[1].name or $..[?(@.name == 'Smith')]

Upvotes: 1

Views: 2375

Answers (3)

Alexander Chudov
Alexander Chudov

Reputation: 11

The answer https://stackoverflow.com/a/43273205/10269029 is completely wrong: variables inside the json path expression are evaluated and can be used at least from JMeter 3.1 (I didn't check earlier versions).

It is even not necessary to add ${__eval()}. Your example doesn't work because you used wrong expression. Correct one should be $[${someInputVariable}].name. There is no dot between $ and [. The JSON was also wrong.

Here is an example jmx with your data that fills the ${NAME-VARIABLE} based on a value of the ${someInputVariable}. To check how it works just save it as jmx, run in JMeter and check variable values on the "Response data" tab of the "Debug PostProcessor" leaf in the "View Results Tree" element. :

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="3.1" jmeter="3.1 r1770033">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" 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" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments">
          <elementProp name="someInputVariable" elementType="Argument">
            <stringProp name="Argument.name">someInputVariable</stringProp>
            <stringProp name="Argument.value">2</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="JSONToBeParsed" elementType="Argument">
            <stringProp name="Argument.name">JSONToBeParsed</stringProp>
            <stringProp name="Argument.value">[{&quot;name&quot;:&quot;a&quot;},{&quot;name&quot;:&quot;b&quot;},{&quot;name&quot;:&quot;c&quot;}]</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
        </collectionProp>
      </Arguments>
      <hashTree/>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" 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>
        <longProp name="ThreadGroup.start_time">1535106337000</longProp>
        <longProp name="ThreadGroup.end_time">1535106337000</longProp>
      </ThreadGroup>
      <hashTree>
        <DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Debug Sampler" enabled="true">
          <boolProp name="displayJMeterProperties">false</boolProp>
          <boolProp name="displayJMeterVariables">true</boolProp>
          <boolProp name="displaySystemProperties">false</boolProp>
        </DebugSampler>
        <hashTree>
          <JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor with constant" enabled="true">
            <stringProp name="JSONPostProcessor.referenceNames">NAME-CONSTANT</stringProp>
            <stringProp name="JSONPostProcessor.jsonPathExprs">$[1].name</stringProp>
            <stringProp name="JSONPostProcessor.match_numbers"></stringProp>
            <stringProp name="Sample.scope">variable</stringProp>
            <stringProp name="Scope.variable">JSONToBeParsed</stringProp>
          </JSONPostProcessor>
          <hashTree/>
          <JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor with variable" enabled="true">
            <stringProp name="JSONPostProcessor.referenceNames">NAME-VARIABLE</stringProp>
            <stringProp name="JSONPostProcessor.jsonPathExprs">$[${someInputVariable}].name</stringProp>
            <stringProp name="JSONPostProcessor.match_numbers"></stringProp>
            <stringProp name="Sample.scope">variable</stringProp>
            <stringProp name="Scope.variable">JSONToBeParsed</stringProp>
          </JSONPostProcessor>
          <hashTree/>
          <DebugPostProcessor guiclass="TestBeanGUI" testclass="DebugPostProcessor" testname="Debug PostProcessor" enabled="true">
            <boolProp name="displayJMeterProperties">false</boolProp>
            <boolProp name="displayJMeterVariables">true</boolProp>
            <boolProp name="displaySamplerProperties">true</boolProp>
            <boolProp name="displaySystemProperties">false</boolProp>
          </DebugPostProcessor>
          <hashTree/>
        </hashTree>
      </hashTree>
      <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
        <boolProp name="ResultCollector.error_logging">false</boolProp>
        <objProp>
          <name>saveConfig</name>
          <value class="SampleSaveConfiguration">
            <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>
            <threadCounts>true</threadCounts>
            <idleTime>true</idleTime>
            <connectTime>true</connectTime>
          </value>
        </objProp>
        <stringProp name="filename"></stringProp>
      </ResultCollector>
      <hashTree/>
    </hashTree>
    <WorkBench guiclass="WorkBenchGui" testclass="WorkBench" testname="WorkBench" enabled="true">
      <boolProp name="WorkBench.save">true</boolProp>
    </WorkBench>
    <hashTree/>
  </hashTree>
</jmeterTestPlan>

Upvotes: 1

Jerome L
Jerome L

Reputation: 637

I have taken a look at JSONPostProcessor source code: https://github.com/apache/jmeter/blob/740dd7420af6ef576af5e6ce2646ede360748691/src/components/org/apache/jmeter/extractor/json/jsonpath/JSONPostProcessor.java

You cannot put variables inside the json path expression as those aren't going to be evaluated. By the way, if you need some help, you can read this article about JMeter json path extractor. It gives way more examples and alternatives to json path extractor.

Upvotes: 1

UBIK LOAD PACK
UBIK LOAD PACK

Reputation: 34566

First you JSON is wrong, it should be:

 [{"name":"a"}, {"name":"b"},{"name":"c"}]

To extract what you want just use the __eval function:

 ${__eval($.[${someInputVariable}].name)}

Upvotes: 5

Related Questions