SoapUI | Test Step | Groovy | Soap Response | List | Nodes | Iteration
Full confession: I am making another post out of frustration. Call it therapy. Why is it that quickly finding information or examples for seemingly simple things is sometimes so !@#$. For those not interested in the full rant, you can jump to the quick solution here.
First, let me say right off the bat that I love soapUI. It has become a defacto standard for running and testing api’s. I use it often to run stuff, test stuff, and check stuff. But, like most such utilities, it’s not the main thrust of my work so I don’t consider myself an expert in all the ins-and-outs of the tool and its capabilities. So, too, with the Apache Groovy language used by soapUI in its test cases. So when I get into the tool in order to solve a specific problem, I want to quickly find examples of what I need to do, modify them for my specific task, and use them. Maybe it’s because soapUI is such a versatile tool, or maybe because the typical soapUI user is already very technical but, often, finding clear examples of some very basic concepts is difficult.
Recently, I found myself in the role of cat wrangler – er, “administrator” – of a host of IBM DataPower IDG devices that front end an army of API’s that are called thousands of times per second. Having grown organically over a number of years and innumerable developers, this system needed some some discipline applied to it. In my quest to document and understand the landscape of these devices and the deployed api’s, I needed a fast way to gather specific information from all the devices, document it, compare it, etc.
IBM for years has provided a set of soap api’s that use AMP (Appliance Management Protocol) with the XML Management Interface on the IDG devices. It’s a full set of api’s that can usually get you the information you need. I have used them for years with soapUI. They are easy to import into a project and I normally just modify the soap request with the values I need, hit the “run” button, and get the soap response. It’s easy enough to scan the responses for the info you require. But in this case, I didn’t want to look at soap responses. I wanted to querry all the devices, parse the responses for the information, and output the information in a report or spreadsheet that I can use to document and analyze.
I knew that soapUI has a great tool where you can create “Test Suites” that have “Test Cases” made up of “Test Steps” used to essentially automate running specific api’s and checking the results with “assertions” to determine pass or fail scenarios. That’s not really what I wanted to do, but I figured I could use the same facility to automate running these IBM api’s, then process and output the results with a Groovy script. The reason I decided to use Groovy has to do with having to loop through lists of servers, execute different api’s, use the results of some api’s to control logic and execute more api’s, etc. I will get into all that in another article, but if you landed on this page by doing a Google search for the keywords in the title, chances are good you have already come to the same decision on using a Groovy test step and probably for the same reasons.
I had little problem setting up the Groovy script to dynamically hit a list of selected servers with my chosen api(s). I tented my fingers like an evil genius as I ran the script and watched as it executed each api call for each server and returned soap responses loaded with the information I required. Now all I had to do was parse each of those responses in turn and output the information in nice, neat little spreadsheet rows. Piece of cake, right?
After each execution of an api, assigning the soap response to a “holder” object with the built in GroovyUtils library is pretty straight forward and it worked as expected. So the next step was to extract the list of nodes that I was interested in and output their various contents. But how?
Well a quick web search should yeild some examples, no? No. At least none that solved my issue. An hour of searching various combinations of “soapUI”, “Groovy”, “iterate node list”, “loop through nodes” etc. kept bringing up the same top results, which were mostly message board posts with similar questions. If you found this article through similar searches, then you have already seen this ubiquitous “sample” code come up way too many times:
Now, I don’t want to criticize this code example too much. It’s fine for what it is and it probably isn’t the snippet creator’s fault that it has been quoted by others and reused in so many places. The problem is that it only works if your response structure is very simple – like with this GetDomainList() api that returns a simple list of domain names from a device. In this case, if you used that example and coded:
for( domain in holder.getNodeValues( “//amp:Domain” ))
You would, indeed iterate through the list of domain elements, with the value of each domain element accessible in the loop variable ‘domain’ each time through:
But what happens when your SOAP response is not so simple? Take this response to the GetServiceListFromDomain() api, for example:
If you need to iterate through the list of “Object” nodes and retrieve the values of the attributes and sub-nodes, using the same code example does not work:
It’s clear from the results above that getNodeValues() will only return a list of strings – not a list of nodes with sub-nodes, elements, and attributes. Since the “Object” nodes in the soap result have no values (only attributes, sub nodes, and elements) getNodeValues() returns only a list of empty strings. So how are we to iterate over the “Object” nodes and retrieve the attributes and values of each?
The solution is to only use getNodeValues() in order to find out how many nodes were returned in the soap response. Then, we will loop that many times through our response object and access each of the attributes and values directly using a loop counter as an index value in the xPath. The below example is based on the same GetServiceListFromDomain() api response illustrated above. Note that inside our loop we are using getNodeValue() and not getNodeValues() in order to return a single string value rather than a list of string values.
Well, there you have it. Born out of my frustration of going down a rabbit hole of web searches looking for a simple way to iterate over list of results nodes and extract attributes and values from sub elements, I give you this little code snippet. For those of you who read through the entire rant, thanks for sticking with me! For those of you who jumped straight to the solution, no worries. If you came here through the same rabbit hole of web searches that I went through, I understand. If you can, post some backlinks to this article on some of the message boards where you see similar questions, or maybe even on your own blogs . Maybe we can get this solution bumped a bit higher up the web search results and save some fellow developers the same frustration in the future.
If you would like more information or examples about how I am using Groovy code inside soapUI Test Suites, Test Cases, and Test Steps to generate output in the form of Excel spreadsheets, leave me a comment and I will get around to making that series of tutorials.