Forum Discussion

JBARRETT5S's avatar
JBARRETT5S
New Contributor
9 years ago

Datasource Loop through JSON data

Hello,

I'm a new user to Soap UI NG pro, and I'm trying to create a test case that will call a resource catalog (rest/json) web service to return information about all the web services it knows about.

Here's an abbreviated example of the json response from the call to the resource catalog...

{
   "AccountAggregationCompute_AMBBOS-LPD0F3":    {
      "ID": "AccountAggregationCompute_AMBBOS-LPD0F3",
      "Service": "AccountAggregationCompute",
      "Tags": [],
      "Address": "http://endpoint:8750/xxx/Risk/BancWare/api/V201701/AccountAggregationCompute",
      "Port": 8750,
      "EnableTagOverride": false,
      "CreateIndex": 0,
      "ModifyIndex": 0
   },
   "AccountBalancingCompute_AMBBOS-LPD0F3":    {
      "ID": "AccountBalancingCompute_AMBBOS-LPD0F3",
      "Service": "AccountBalancingCompute",
      "Tags": [],
      "Address": "http://endpoint:8750/xxx/Risk/BancWare/api/V201701/AccountBalancingCompute",
      "Port": 8750,
      "EnableTagOverride": false,
      "CreateIndex": 0,
      "ModifyIndex": 0
   },
}

In the above, there are two web services defined.  (You can see the full json response in the attached.)

After I get this response, I want to loop through each service node, and pull out the "Service" value for that node/group.  I then want to use that service name in another GET request later in the test case.

Anyway, I thought I could use a Json Datasource w/ Loop structure to go through each json node, and return the Service value, but I can't seem to get this to work.

I defined a JSON DataSource that references the catalog response, but I can't seem to define the correct Row and Column Path to allow the DS Loop to later increment to the next Json node.  It only processes the first node and then exits.

Do you know what the Row and Column (jsonpath) Paths should be here?  I've tried many expressions, including $..Service, which does work at https://jsonpath.curiousconcept.com, but doesn't seem to work in my Datasource.

Maybe this isn't a valid approach?  Should I be using a Groovy to parse this data instead?

Thanks for any feedback.

Jim

  • I dont know if this will help or not.

     

    I was playing around with this a couple of week's ago - not specifically for work - I just hadn't used the groovy/xml/json datasources before so started to play around with the functionality.

     

    I had a LOT of trouble with json datasource, perhaps I was doing something wrong (I also find xpath easier to read than jsonpath)  - but I found setting it up was a lot easier if I used an XML datasource instead.

     

    Despite the fact that the response of the request that I was using to populate my datasource was actually .json  - I added the XML datasource in and specified the 'source property' dropdown on the XML datasource as 'ResponseAsXML'.

     

    I was then able to build up a datasource of attributes successfully sourced from the response without too much trouble.

     

    Just a suggestion,

     

    Cheers,

     

    richie

  • JBARRETT5S's avatar
    JBARRETT5S
    New Contributor

    Thank you Rao.  I appreciate the feedback.

    Your response pointed me in the direction of using a Groovy Script step to meet my goal.

    Here' the script I ended up using...

     

    // Get the Json response from the Catalog Service GET.
    def jsonResponse = context.expand( '${GET Catalog Services#Response}' )
    def parsedJson = new groovy.json.JsonSlurper().parseText(jsonResponse)

     

    // Loop thru each service that's defined in the response...
    def iNumServices = 0
    def checkStatusStep = "CHECK Service Status"
    parsedJson.each { serviceNode ->
     if (serviceNode.value.Service != 'consul') {

      iNumServices = iNumServices + 1
      
      //Store the next service name in testcase property 'ServiceName'.
      //The <CHECK Service Status> step will retrieve the service name from this property.
      testRunner.testCase.setPropertyValue("ServiceName", serviceNode.value.Service)

     

      //Perform a GET on this web service and check the response status.
      //If the response status code is NOT 200, an assertion will be logged.
      log.info "Checking ALIVE status for service ->" + serviceNode.value.Service
      testRunner.runTestStepByName(checkStatusStep )
     }
    }
    assert iNumServices >= 1 : "No services returned by Resource Catalog!"
    testRunner.gotoStepByName("The End")

     

  • PBell's avatar
    PBell
    Occasional Contributor

    Can we accomplish this with only the JSON DataSource and not a groovy script?  I have some testers who aren't that adept at groovy. 

     

    I set my RowPath as $[*] and my Column Path as the values for the JSON names I want to pull in.  This gets 0 rows.

     

    When I set my RowPath as $[0] with the same ColumnPath I get 1 row.  Why can't I use $[*] to get all rows to populate my DataSource?  Why do I have to use groovy to accomplish this?

    • richie's avatar
      richie
      Community Hero

      I dont know if this will help or not.

       

      I was playing around with this a couple of week's ago - not specifically for work - I just hadn't used the groovy/xml/json datasources before so started to play around with the functionality.

       

      I had a LOT of trouble with json datasource, perhaps I was doing something wrong (I also find xpath easier to read than jsonpath)  - but I found setting it up was a lot easier if I used an XML datasource instead.

       

      Despite the fact that the response of the request that I was using to populate my datasource was actually .json  - I added the XML datasource in and specified the 'source property' dropdown on the XML datasource as 'ResponseAsXML'.

       

      I was then able to build up a datasource of attributes successfully sourced from the response without too much trouble.

       

      Just a suggestion,

       

      Cheers,

       

      richie

      • PBell's avatar
        PBell
        Occasional Contributor

        Thanks Richie!  That fixed it for me.  This makes me think that the JSON DataSource has a bug in it.  The XML DataSource works just like I thought the JSON DataSource would.  I have my workaround now that is less complex than the Groovy DataSource.