HOWTO: Verify that every element of a server's response is valid using SoapUI

It has been a while since my last blog entry, so I though that I would write something up about a recent problem that I had to solve.

Here is the problem that I was faced with: Send a request to a server, make sure that every element of an array in the response is valid.

My initial approach was to convert the JSON response to a XML object and then traverse the object hierarchy verifying only the elements we are interested in.
Below you will find both scripts that solve my problem.

1) XML Method:

// Library to allow traversal of the XML document
import com.eviware.soapui.support.XmlHolder
 
// expected value that we need to check
def expected = "eng"
 
// name of the node we need to check
def elementName = "language"
 
// Server address of the endpoint. This will be used to configure a namespace string.
def server = context.expand( '${#Project#endpoint}' )
 
// Convert server's response to the XML document
def holder = new XmlHolder( messageExchange.responseContentAsXml )
 
// set the namespace
holder.namespaces["ns1"] = server + "/listings"
 
// get the root node of the document
def results = holder.getDomNode( "//ns1:Response[1]" )
 
def checkResponse(expectedValue, rootNode, nodeName) {
     // see if current node's name matches the name of the node we are looking for
     if (rootNode.getNodeName() == nodeName) {
          // if current node has children, get the first child.
          // this is done because there are a lot of weird nodes added during conversion from JSON to XML
          if (rootNode.hasChildNodes()) {
               rootNode = rootNode.getFirstChild()
          }
          // get value of the current node
          def actual = rootNode.getNodeValue()
          if (expectedValue != "") {
               // make sure that expected value is included in the node.
               // we are using 'indexOf' instead of '==' here because in case of language checking value could look like: 'eng, spa'
               assert expectedValue.indexOf(actual) >= 0
          }
     }
 
     // otherwise, iterate over the child nodes of and call this function recursively
     def nodes = rootNode.getChildNodes()
     for (def node in nodes) {
          checkResponse(expectedLang, node, nodeName)
     }
}
 
checkResponse(expected, results, elementName)

2) JSON Method:

// include required libary to convert JSON string to JSON object
import groovy.json.JsonSlurper
 
// specify expected value
def expected = "eng"
 
// convert TestStep's response to a JSON object
def json = new JsonSlurper().parseText(messageExchange.responseContent)
 
// get a reference to the element that has an array of objects of interest
def nodes = json.results
 
// iterate over each element in the array
for (i = 0; i < nodes.size(); i++) {
     // verify that field's value matches our expectations
     // we are using 'indexOf' instead of '==' here because in case of language checking value could look like: 'eng, spa'
     assert nodes[i].channel.language.indexOf(expected) >= 0, "Channel language was not ${expected}"
}

I, personally, think that JSON Method is a better approach from both the carpal tunnel perspective and, more importantly, because you are not changing data types around.

As always, questions and comments are welcomed.

Comments