4

In one of my tests I need to check that the data in an array matches to an expected result. I send an API call and receive the following JSON response:

{
"sting": "value",
"another string": "value",
"array": ["value1","value2","value3"]
}

Using the JSON Path Assertion plugin I'm able to check each value individually.

$.array[0]

Is there a way to evaluate all the array's values in one assertion?

PurpleBeni
  • 459
  • 4
  • 10
  • 17

2 Answers2

3

Looking into Can't check an array with JSONPath Assertion. Update JSONPath to 2.1? currently it is not possible.

You can work it around using Response Assertion instead as follows:

  1. Add JSON Path Extractor as a child of the request which returns above JSON and configure it as follows:

    • Destination Variable Name: anything meaningful, i.e. array
    • JSON Path Expression: $.array
  2. Add Response Assertion after the JSON Path Extractor and configure it as follows:

    • Apply to -> JMeter Variable -> array
    • Pattern Matching Rules: Equals
    • Patterns to Test: ["value1","value2","value3"] - make sure there are no trailing spaces, new lines, etc.

      Response Assertion

Example Test Plan:

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.8" jmeter="2.13 r1665067">
  <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.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>
      <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>
        <longProp name="ThreadGroup.start_time">1456157004000</longProp>
        <longProp name="ThreadGroup.end_time">1456157004000</longProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
      </ThreadGroup>
      <hashTree>
        <kg.apc.jmeter.samplers.DummySampler guiclass="kg.apc.jmeter.samplers.DummySamplerGui" testclass="kg.apc.jmeter.samplers.DummySampler" testname="jp@gc - Dummy Sampler" enabled="true">
          <boolProp name="WAITING">true</boolProp>
          <boolProp name="SUCCESFULL">true</boolProp>
          <stringProp name="RESPONSE_CODE">200</stringProp>
          <stringProp name="RESPONSE_MESSAGE">OK</stringProp>
          <stringProp name="REQUEST_DATA">Dummy Sampler used to simulate requests and responses
without actual network activity. This helps debugging tests.</stringProp>
          <stringProp name="RESPONSE_DATA">{
&quot;sting&quot;: &quot;value&quot;,
&quot;another string&quot;: &quot;value&quot;,
&quot;array&quot;: [&quot;value1&quot;,&quot;value2&quot;,&quot;value3&quot;]
}</stringProp>
          <stringProp name="RESPONSE_TIME">${__Random(50,500)}</stringProp>
          <stringProp name="LATENCY">${__Random(1,50)}</stringProp>
          <stringProp name="CONNECT">${__Random(1,5)}</stringProp>
        </kg.apc.jmeter.samplers.DummySampler>
        <hashTree>
          <com.atlantbh.jmeter.plugins.jsonutils.jsonpathextractor.JSONPathExtractor guiclass="com.atlantbh.jmeter.plugins.jsonutils.jsonpathextractor.gui.JSONPathExtractorGui" testclass="com.atlantbh.jmeter.plugins.jsonutils.jsonpathextractor.JSONPathExtractor" testname="jp@gc - JSON Path Extractor" enabled="true">
            <stringProp name="VAR">array</stringProp>
            <stringProp name="JSONPATH">$.array</stringProp>
            <stringProp name="DEFAULT"></stringProp>
            <stringProp name="VARIABLE"></stringProp>
            <stringProp name="SUBJECT">BODY</stringProp>
          </com.atlantbh.jmeter.plugins.jsonutils.jsonpathextractor.JSONPathExtractor>
          <hashTree/>
          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
            <collectionProp name="Asserion.test_strings">
              <stringProp name="-1728402013">[&quot;value1&quot;,&quot;value2&quot;,&quot;value3&quot;]</stringProp>
            </collectionProp>
            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
            <boolProp name="Assertion.assume_success">false</boolProp>
            <intProp name="Assertion.test_type">8</intProp>
            <stringProp name="Assertion.scope">variable</stringProp>
            <stringProp name="Scope.variable">array</stringProp>
          </ResponseAssertion>
          <hashTree/>
        </hashTree>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

If your response may vary, i.e. array members order changes, you might need to consider scripting-based assertion, i.e. JSR223 Assertion instead

See How to Use JMeter Assertions in Three Easy Steps guide for comprehensive information on using JMeter Assertions in your tests.

Dmitri T
  • 159,985
  • 5
  • 83
  • 133
  • This doesn't work. When I run the test I receive the following error: Test failed: variable(array) expected to match /["value1","value2","value3"]/ @Dmitri T – PurpleBeni Feb 25 '16 at 12:53
  • Yes you are correct. However the first sentence in your comment was unnecessary. @Dmitri T – PurpleBeni Mar 01 '16 at 14:44
0

I was able to get this to work by using the .. syntax. In your case, it would be $..array which would return

[
    "value1",
    "value2",
    "value3"
]

Then you could, for example, check the "additionally assert value" box and "match as regular expression" and then do \w+ as the expected value, asserting that there is a word there.

Brian Davis
  • 745
  • 1
  • 11
  • 14