Forum Discussion

ripkurrle's avatar
ripkurrle
Occasional Contributor
5 years ago

DataSource Loop with variable number of child elements

Hi

I've just started using ReadyAPI 3.4.5 after being on SoapUI for a while.

I'm testing an external vendor API and trying to pass in all my scenario data through one DataSource, ideally.

My problem is that each of the test cases has a different number of elements applied to a complex element, e.g. Test 1 may have the following elements for specifying contributions

...

<contributions>

  <contribution>

    <type>Single</type>

    <amount>1000</type>

  </contribution>

    <type>Regular</type>

    <amount>100</type>

    <startDate>1-1-2020</startDate>

  </contribution>

...

The next test might only have one Single contribution defined. There are a few complex elements that I adjust for each test and have a similar problem.

 

I've set the flag for "Remove Empty Content" to try and remove any elements where nothing is passed in from the DataSource but this leaves the parent node empty "<contribution></contribution>" which unfortunately breaks the test.

 

I've researched ways that this might be able to be resolved using Events with RequestFilter.filterRequest but the supplied groovy script doesn't appear to work well with DataSource data, instead it passes the property name in as a string to the request, e.g. ${DataSource#Single-Amount}

See section 4.5 in https://www.soapui.org/docs/scripting-and-properties/tips-tricks/ and https://support.smartbear.com/readyapi/docs/testing/scripts/samples/xml.html

Seems like a similar issue was raised here but the user didn't confirm whether it fixed their problem or not

https://community.smartbear.com/t5/API-Functional-Security-Testing/Remove-Empty-Content/td-p/18426 

 

The only way I can think of getting around this is not using the DataSource at all and, instead, crafting each test step as a specific test. I'm not a tester by profession so perhaps this is the way more seasoned testers craft tests when they have these limitations, I just wanted to control the test data from the one view point.

 

I also thought a RegEx over the expanded request, with DataSource data populated in, just before it gets sent I could replaceAll some of the fields but couldnt work out an event or script to get the XML at this point.

 

Cheers

Alan

  • Hey ripkurrle,

    I wouldve picked the same event handler you did to handle the empty root element, but ive never tried events on datasourced data before.

    Rather than have to go with the individual test data approach on each test step, im wondering if perhaps your datasource step passed the data to a datasource grid (as an intermediate step before being sourced by the Rest step, perhaps this would work? I know the datasource grid is a datasource step, but it might work?

    I.e. datasource step &gt;&gt; datasource grid (with expanded data) event handler processes this data &gt;&gt; REST step sources data from datasource grid

    Or, i'm wondering if you have a datasource that writes to a properties file, groovy step to remove the empty elements and then the REST step (sourcing the data from the Properties step via ${Properties#testdata}) to submit the request which doesnt contain any empty elements? Actually id do it this way i think, so my test step object hierarchy would be as follows:

    Datasource step
    Properties step
    Groovy step
    Properties2 step (optional)
    REST step

    Groovy step would contain something like the following (code = courtesy of


    def xmlString = """<PROFILE> <NAME>Fin</NAME> <AGA>20</AGA> <CONTACT> <MOBILE>1819</MOBILE> <TELEPHONE></TELEPHONE> </CONTACT> <TEAM> <TEAM1></TEAM1> <TEAM2></TEAM2> </TEAM> </PROFILE>"""

    def xml = new XmlParser().parseText(xmlString) def nodes = xml.'**'.findAll{it.name() &amp;&amp; !it.text()} def removeNode = { node -&gt; def parent = node.parent() parent.remove(node) } nodes.each{removeNode(it)} println groovy.xml.XmlUtil.serialize

    Ta

    Rich
  • richie's avatar
    richie
    Community Hero
    Hey ripkurrle,

    I wouldve picked the same event handler you did to handle the empty root element, but ive never tried events on datasourced data before.

    Rather than have to go with the individual test data approach on each test step, im wondering if perhaps your datasource step passed the data to a datasource grid (as an intermediate step before being sourced by the Rest step, perhaps this would work? I know the datasource grid is a datasource step, but it might work?

    I.e. datasource step &gt;&gt; datasource grid (with expanded data) event handler processes this data &gt;&gt; REST step sources data from datasource grid

    Or, i'm wondering if you have a datasource that writes to a properties file, groovy step to remove the empty elements and then the REST step (sourcing the data from the Properties step via ${Properties#testdata}) to submit the request which doesnt contain any empty elements? Actually id do it this way i think, so my test step object hierarchy would be as follows:

    Datasource step
    Properties step
    Groovy step
    Properties2 step (optional)
    REST step

    Groovy step would contain something like the following (code = courtesy of


    def xmlString = """<PROFILE> <NAME>Fin</NAME> <AGA>20</AGA> <CONTACT> <MOBILE>1819</MOBILE> <TELEPHONE></TELEPHONE> </CONTACT> <TEAM> <TEAM1></TEAM1> <TEAM2></TEAM2> </TEAM> </PROFILE>"""

    def xml = new XmlParser().parseText(xmlString) def nodes = xml.'**'.findAll{it.name() &amp;&amp; !it.text()} def removeNode = { node -&gt; def parent = node.parent() parent.remove(node) } nodes.each{removeNode(it)} println groovy.xml.XmlUtil.serialize

    Ta

    Rich
      • TanyaYatskovska's avatar
        TanyaYatskovska
        SmartBear Alumni (Retired)

        Thanks for the help, richie!

        ripkurrle, was the issue resolved? Please let us know if you need more help.