cancel
Showing results for 
Search instead for 
Did you mean: 

Get all Nodes Names and values from a test case Response

SOLVED
Contributor

Get all Nodes Names and values from a test case Response

Hello @All,

 

i am trying to retrieve Node names and values from a SOAP response received by a webservice's method that I test.

Here is my code and I attach the output as a file:

import groovy.util.XmlSlurper;
import groovy.util.slurpersupport.*;

// create groovyUtils and XmlHolder for response of the request
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
def requestResponse = groovyUtils.expand('${CheckSdcAuthorisation[8.2]#Response}');
def holder = groovyUtils.getXmlHolder(requestResponse);
def parseResponse = new XmlSlurper().parseText(requestResponse);
def allNodeValues = holder.getNodeValues("//*");

// loop item nodes in response message
for( item in allNodeValues){
log.info "Item : [$item]"
}

The issue is that I'm not able to get node names and corresponding values. I do not understand why the for loop does not return Node values as expected? Also what code should I change to replace Item by the name of the node?
Do you have any suggestion to solve my issue?

1 ACCEPTED SOLUTION

Accepted Solutions
Community Hero

Re: Get all Nodes Names and values from a test case Response

This is going to require some groovy scripting, without a doubt. There's a feature that you can use in groovy to directly compare two xml statements called XMLUnit. You can see some of the specifics of it here and here.

 

Here's a snippet of code that'll compare XML:

 

import org.custommonkey.xmlunit.*;

XMLUnit.setIgnoreWhitespace(true)
XMLUnit.setIgnoreComments(true)
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(false)
XMLUnit.setNormalizeWhitespace(true)

def request1Xml = context.expand( '${Request1#Response}' )
def request2Xml = context.expand( '${Request2#Response}' )

Diff diff = new Diff (request1Xml, request2Xml);

DetailedDiff myDiff = new DetailedDiff (diff);

log.info(myDiff);

This will give a relatively detailed difference between the two XML responses. That might give you what you want.




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
17 REPLIES 17
Community Hero

Re: Get all Nodes Names and values from a test case Response

What use case are you trying to build here with this script? Groovy scripts are powerful, but can become very complex very quickly and may actually be a bad solution in some cases.




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
Community Hero

Re: Get all Nodes Names and values from a test case Response

I believe that you had some question earlier, might be related? it was said that you wanted to compare, and it is marked answered.


Regards,
Rao.
Community Hero

Re: Get all Nodes Names and values from a test case Response

By the way, all nodes can't have values i.e., complex nodes inturn have child nodes as values.

It would be appreciated if you provide more details on what are you trying to achieve, then some one will be in a good position to offer better help.


Regards,
Rao.
Community Hero

Re: Get all Nodes Names and values from a test case Response

I threw together a groovy script that I've been working on for my own use that fits what you are looking for. This script will parse every element in the Body of the response that contains actual data. Adjust as necessary.

 

import groovy.util.XmlSlurper;
import groovy.util.slurpersupport.*;

// create groovyUtils and XmlHolder for response of the request
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
def requestResponse = groovyUtils.expand('${ChangedSinceDate#Response}');
def holder = groovyUtils.getXmlHolder(requestResponse);
def parseResponse = new XmlSlurper().parseText(requestResponse);

// loop item nodes in response message

def mapConstruct(mapNodes) {
    mapNodes.children().collectEntries 
    { 
        [ 
        	it.name(), it.childNodes() ? mapConstruct(it) : it.text() 
        ] 
    }
}

def parseMaps(Map map, int counter = 0, org.apache.log4j.Logger log)
{
	map.each
	{
		k, v -> 
		// log.info("$k");
		if (v.getClass().toString() == "class java.util.LinkedHashMap")
		{
			// log.info("recurse case $v");
			parseMaps(v, counter++, log);
		}
		else
		{	
			// log.info("base case");
			if (v.size() > 0)
			{
				log.info("$k has a value of $v");
			}
		}
	}
}

def map = mapConstruct(parseResponse);

log.info(map.getClass());

String [] keySet = map.keySet().toArray();

log.info(keySet.size());

parseMaps(map["Body"], 0, log);




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
Contributor

Re: Get all Nodes Names and values from a test case Response

Thanks for you replies both! Yes, my issue is not solved at all @nmrao but as the topic of my preceding subject was particular and the reply of @msiadak was related to what I aked, I marked it as solve.

I did not take the time to take a look on your script @msiadak but I will, and really thanks to have shared it for my use.

I will precise my need, maybe you could help me to think and tell me about the best method to do it.

In my work, following the migration of a web service, I have to send a wide range of requests in order to be the most exhaustive as possible to test two differents binding interface. The requests sent must be exactly the same from one binding interface to the other.

My test must idenfy the discrepancies between both received response. So what's the best method to achieve that ?

Knowing that, in general cases where everything is good, I can create a simple contains assertion based on a "Get Data" retrieving which permit me to compare the content of both responses.


In particular cases, where services integrate business logic, I am forced to use a complex message assertion which I set line by line.
In my test case, I create 4 steps :
1) Response from first binding interface.
2) A propety transfer step where I create a transfer value for each node in my xml response from the first binding interface. 3) A properties step where I created a property for each node value (the name of the property is the name of my node) and the value is filled thanks to my property transfer step.
4) Response from the second binding inteface where the complex message assertion is set. This allow me to compare the expected result from Response1 (Node value) to the actual result (Node value from Response 2) one by one.
Reasoning is pretty simple, but the issue appears when responses received are really long for instance thousands of xml line; it takes me hours and sometimes days to build my test, and it's really heavy to implement it.

As I'm new in testing domain in using SoapUI Pro and not so familiar in programming languages in general and especially in groovy, it's really complicated for me to set up an automated process to point out every difference from this use case.
Moreover, as I'm alone as tester in my team, I need to build everything by myself, and my technical knowledge does not permit me to find the best way to achieve my purpose.

So let's discuss about your suggestions, you have really more experience than I have so may be you will have some ideas and show me the best way to avoid wasting time!

If you need more details, I would be happy to provide you more.
Also, do not hesitate to tell me if I did not present the subject clearly.

I hope that we wil have a great collaboration together!


Community Hero

Re: Get all Nodes Names and values from a test case Response

So if I understand what you are trying to do, you want to take Response1 from one interface and compare it to Response2 from a second interface and ensure that they are the same. If not, you want to see / know what the differences are? Does that sound like the basic idea?




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
Contributor

Re: Get all Nodes Names and values from a test case Response

Yes @msiadak it's exactly the point!

Community Hero

Re: Get all Nodes Names and values from a test case Response

This is going to require some groovy scripting, without a doubt. There's a feature that you can use in groovy to directly compare two xml statements called XMLUnit. You can see some of the specifics of it here and here.

 

Here's a snippet of code that'll compare XML:

 

import org.custommonkey.xmlunit.*;

XMLUnit.setIgnoreWhitespace(true)
XMLUnit.setIgnoreComments(true)
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(false)
XMLUnit.setNormalizeWhitespace(true)

def request1Xml = context.expand( '${Request1#Response}' )
def request2Xml = context.expand( '${Request2#Response}' )

Diff diff = new Diff (request1Xml, request2Xml);

DetailedDiff myDiff = new DetailedDiff (diff);

log.info(myDiff);

This will give a relatively detailed difference between the two XML responses. That might give you what you want.




---

Click the Accept as Solution button if my answer has helped, and remember to give kudos where appropriate too!
Contributor

Re: Get all Nodes Names and values from a test case Response

Thanks for you reply and for helping me! It's really nice!

Will it create an array of every difference from both responses or something like that to identify each diff? Or only report to the console one difference as global mismatching if there is at least one?

Regards

New Here?
Join us and watch the welcome video:
Watch the new Interview
Top Kudoed Authors