MrTunaDeluxe
MrTunaDeluxe

Reputation: 152

Groovy script assertion to verify attributes in XML response to values in CSV file in script

I'm currently using SoapUI to make a call to a webservice based on a value I've pulled from my CSV file in another script (Located here for those interested). What I'd like to do is parse the response of that webservice call to verify that the externalId values for every Subscriber element match the ones in the CSV file (which are are saved in the test case properties via the other script), and that there aren't any extra/less being returned.

An example of the soap response is seen below.

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header/>
   <env:Body>
      <ws:searchResponse xmlns:ws="http://ws.web.blah.com">
         <result dataUpdated="false">
            <Subscriber lastReportDate="2014-05-28T11:00:02-03:00" externalId="20107A-R29O12KH11113233" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="803227" macAddress="D2:9F:EE:11:32:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber ip="11.13.23.33" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132333" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101553" macAddress="AB:CD:11:13:23:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber ip="11.13.23.32" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132332" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101550" macAddress="AB:CD:11:13:23:32" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber ip="11.13.23.31" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132331" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101545" macAddress="AB:CD:11:13:23:31" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber ip="11.13.23.23" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132323" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101542" macAddress="AB:CD:11:13:23:23" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber ip="11.13.23.22" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132322" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101537" macAddress="AB:CD:11:13:23:22" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber ip="11.13.23.21" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132321" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101533" macAddress="AB:CD:11:13:23:21" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber externalId="32321070" neighborhoodID="103290" neighborhood="PMBKXXDSL11" city="TORO" nodeId="100942" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber externalId="PMBKONOLT11:3-2-3-2-1070" neighborhoodID="103290" neighborhood="PMBKXXDSL11" city="TORO" nodeId="100941" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber lastReportDate="2014-05-28T12:00:01-03:00" externalId="001404-D29247113233" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="100716" macAddress="D2:9D:CC:11:32:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
            <Subscriber lastReportDate="2014-05-28T12:00:01-03:00" externalId="001A73-WECO10KH11113233" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="100414" macAddress="D2:9A:BB:11:32:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
         </result>
      </ws:searchResponse>
   </env:Body>
</env:Envelope>

What I was thinking for a solution would be something along the lines of:

Unfortunately I'm very new to Groovy and SoapUI, and I'm unsure of how to really implement this, so if anyone has any ideas or tips it would be greatly appreciated!

Upvotes: 0

Views: 2881

Answers (1)

Ori Dar
Ori Dar

Reputation: 19020

I suggest another alternative:

  1. Read all Subscriber externalId attributes from the Web Service into a String list and sort the list.
  2. Read all CSV values into a String list and sort the list.
  3. Assert the two lists are same.

You can use this example as a basis. What you are left to do is:

  1. Replace the XmlSlurper.parseText() with XmlSlurper.parse() using the Web Service URI.
  2. I don't see any value in keeping the static externalId list as a CSV file. Instead I've used a simple file where each line contains an externalId (no comma separated). Using CSV instead should be fairly easy.

The XML as String:

def xml = "<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
    "   <env:Header/>\n" +
    "   <env:Body>\n" +
    "      <ws:searchResponse xmlns:ws=\"http://ws.web.blah.com\">\n" +
    "         <result dataUpdated=\"false\">\n" +
    "            <Subscriber lastReportDate=\"2014-05-28T11:00:02-03:00\" externalId=\"20107A-R29O12KH11113233\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"803227\" macAddress=\"D2:9F:EE:11:32:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber ip=\"11.13.23.33\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132333\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101553\" macAddress=\"AB:CD:11:13:23:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber ip=\"11.13.23.32\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132332\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101550\" macAddress=\"AB:CD:11:13:23:32\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber ip=\"11.13.23.31\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132331\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101545\" macAddress=\"AB:CD:11:13:23:31\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber ip=\"11.13.23.23\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132323\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101542\" macAddress=\"AB:CD:11:13:23:23\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber ip=\"11.13.23.22\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132322\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101537\" macAddress=\"AB:CD:11:13:23:22\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber ip=\"11.13.23.21\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132321\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101533\" macAddress=\"AB:CD:11:13:23:21\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber externalId=\"32321070\" neighborhoodID=\"103290\" neighborhood=\"PMBKXXDSL11\" city=\"TORO\" nodeId=\"100942\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber externalId=\"PMBKONOLT11:3-2-3-2-1070\" neighborhoodID=\"103290\" neighborhood=\"PMBKXXDSL11\" city=\"TORO\" nodeId=\"100941\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber lastReportDate=\"2014-05-28T12:00:01-03:00\" externalId=\"001404-D29247113233\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"100716\" macAddress=\"D2:9D:CC:11:32:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "            <Subscriber lastReportDate=\"2014-05-28T12:00:01-03:00\" externalId=\"001A73-WECO10KH11113233\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"100414\" macAddress=\"D2:9A:BB:11:32:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
    "         </result>\n" +
    "      </ws:searchResponse>\n" +
    "   </env:Body>\n" +
    "</env:Envelope>"

Retrieve the subscribers node list:

def subscribers = new XmlSlurper(false, true).parseText(xml).Body.searchResponse.result.Subscriber
// Replace parseText with parse(uri)

Transform the XML Subscriber elements into a list of String:

def idsFromSoap = subscribers.collect{[email protected]()}.sort()

The collect() method transforms Subscriber nodes into a list of (externalId attribute ) String via [email protected](). The transformed String list is then sorted.

Now, create a file with the following content:

12345678-1234-ABCD-ABCD-ABCD11132321
001404-D29247113233
001A73-WECO10KH11113233
12345678-1234-ABCD-ABCD-ABCD11132322
PMBKONOLT11:3-2-3-2-1070
12345678-1234-ABCD-ABCD-ABCD11132323
32321070
12345678-1234-ABCD-ABCD-ABCD11132333
20107A-R29O12KH11113233
12345678-1234-ABCD-ABCD-ABCD11132331
12345678-1234-ABCD-ABCD-ABCD11132332

I've scrambled the ids on purpose. I've called it ids.csv even though it's not a CSV file of course.

Read the file lines into (implicit) list of String and sort:

def idsFromFiles = new File("ids.csv").readLines()*.trim().sort()

* is the spread operator meaning every item in the list read using readLines() is trimmed (you don't have trim if the file lines are kept with no spaces).

Finally, compare the two lists to verify they contain the same items:

assert idsFromSoap == idsFromFiles

EDIT

As to your comments: Yes. parse(String) accepts a valid URL such as ws.web.blah.com and parses the response, as long as the response is a valid XML/XHTML. So you can skip using SOAP UI altogether, and just invoke the URL.

how does that get the entire response without dealing with the context variable?

It has nothing to do with SOAP UI context at all.

As for SOAP UI, I'm not familiar with the API. But as long as you can save the response to a String (or File/Stream and use the overloaded parse() methods), the code should work.

Upvotes: 2

Related Questions