All about SOAP UI and Groovy in it

Posts tagged ‘getXmlHolder script assertion’

Using Script Assertion in SOAP UI

Script assertion in SOAP UI helps the developer to immediately run some primary tests after the current messageExchange.

It feels/sounds similar to Groovy Script test step but, in a lot ways it’s more handy. If say we want to validate on the response time and proceed further for succeeding test steps, it feels heavy to have a Groovy step to do that; instead, the Script Assertion implicitly does that job (can be done using “assert messageExchange.timeTaken < 1000”). Using this we could make the Test Suite look more credible and modular.

Script Assertion has access to messageExchange, context and log objects.

We can access the request and response xml as below –

def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )

def requsetHolder = groovyUtils.getXmlHolder( messageExchange.requestContent )

def responseHolder = groovyUtils.getXmlHolder( messageExchange.responseContent )

using the above holders we can get hold of the all elements in response and request xml of the latest messageExchange.

While accessing the elements of request/response xml, using the corresponding namespace(s) for every element is very important. If the response xml is simple (that is, mostly all the elements are referenced by one namespace), then xpath would be simple to trace. But if various elements are referenced by various namespaces, then we should be cautious while framing the xpath.

Here are my observations regarding this:

Lets say following is the response xml obtained after running the Test Request step(which has the script assertion)

Sample Response xml

Sample Response xml - I

In the Script Assertion step, to access RefNum field (of the above response xml), we write

def refNum = responseHolder.getNodeValue(“//trans:ProcessMessageResponse/content/Response/RefNum”)

And say if the response xml has various namespaces to refer its elements as below

Sample Response xml - II

then to access the same RefNum value, the xpath used should be

def refNum = responseHolder.getNodeValue(“//trans:ProcessMessageResponse/ns1:content/ns2:Response/ns2:RefNum”)

or

def refNum = responseHolder.getNodeValue(“//ns2:Response/ns2:RefNum”)

This might raise some ambiguity regarding ‘ns2‘ namespace ref. which I have used to access the RefNum value, though it is nowhere present in the response xml.

What I figured out is default namespaces are named as ns1, ns2 and so on (as applicable) in the order of their occurrences. In the above xml, ‘content‘ element is referred with ‘ns1’; and ‘Response‘ element is referred with ‘ns2’. And thus the xpath is so.

We can verify which namespace is given which name, by clicking the ‘Declare’ button in XPath Assertion window (though this can be done to know the names of different namespaces present in response xml only). But to know, the names of different namespaces present in request xml, ordering logic (what i have mentioned above) should be employed.

Not only while applying Script Assertion, the above explanation (that is, building precise xpath with appropriate namespace references) applies to all the situations where developer needs to access any element of request/response xmls.