Identifying multiple values in SOAP UI response with Groovy - groovy

I was recently helped through a problem here where I wanted to identify multiple values from a SOAPUI response. This was successfully answered here.
I tried to take this same approach to a new problem I have. This time I would like to pick up 4 values from each section to use as my expected results.
Below is an example of my response that I want to run the assert expected results against:
<ns1:LimitAndUsageDetailsList>
<ns2:LimitAndUsageDetails xmlns:ns2="http://www.">
<ns2:LimitCode>022</ns2:LimitCode>
<ns2:LimitCodeDesc>APPLIANCES</ns2:LimitCodeDesc>
<ns2:LimitType>N</ns2:LimitType>
<ns2:LimitBenefit>500.0</ns2:LimitBenefit>
<ns2:LimitBenefitUsed>0.0</ns2:LimitBenefitUsed>
<ns2:LimitBenefitAvailable>500.0</ns2:LimitBenefitAvailable>
<ns2:LimitBenefitService>0</ns2:LimitBenefitService>
<ns2:LimitBenefitUsedService>0</ns2:LimitBenefitUsedService>
<ns2:LimitBenefitAvailableService>0</ns2:LimitBenefitAvailableService>
<ns2:QualifyingPeriodIndicator/>
<ns2:ClaimIndicator>B</ns2:ClaimIndicator>
<ns2:LimitPeriod>1</ns2:LimitPeriod>
<ns2:LimitPeriodType>C</ns2:LimitPeriodType>
<ns2:LimitScale>INDIV</ns2:LimitScale>
</ns2:LimitAndUsageDetails>
<ns2:LimitAndUsageDetails xmlns:ns2="http://www.">
<ns2:LimitCode>023</ns2:LimitCode>
<ns2:LimitCodeDesc>NEBULISER</ns2:LimitCodeDesc>
<ns2:LimitType>N</ns2:LimitType>
<ns2:LimitBenefit>0.0</ns2:LimitBenefit>
<ns2:LimitBenefitUsed>0.0</ns2:LimitBenefitUsed>
<ns2:LimitBenefitAvailable>0.0</ns2:LimitBenefitAvailable>
<ns2:LimitBenefitService>1</ns2:LimitBenefitService>
<ns2:LimitBenefitUsedService>0</ns2:LimitBenefitUsedService>
<ns2:LimitBenefitAvailableService>1</ns2:LimitBenefitAvailableService>
<ns2:QualifyingPeriodIndicator/>
<ns2:ClaimIndicator>B</ns2:ClaimIndicator>
<ns2:LimitPeriod>3</ns2:LimitPeriod>
<ns2:LimitPeriodType>R</ns2:LimitPeriodType>
<ns2:LimitScale>INDIV</ns2:LimitScale>
</ns2:LimitAndUsageDetails>
And I am interested in LimitCode, LimitType, LimitPeriod and LimitPeriodType elements.
I have tried the following assert script but it doesnt work.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( messageExchange.responseContent )
def pxml = new XmlSlurper().parseText(context.response)
def expected = [
"022":"N":"1":"C"
'023':'N':'3':'R',
'030':'N':'1':'C',
]
def xml = new XmlSlurper().parseText(context.response)
def actual = xml.'**'.findAll{it.name() == 'LimitAndUsageDetails'}.collectEntries{[(it.LimitCode.text()): it.LimitType.text(): it.LimitPeriod.text(): it.LimitPeriodType.text()]}
assert expected == actual

Here is what you need to do.
Expected data requires couple more items as opposed to previous question.
So need to create map(to identify which data to what element)
Since there are list of details to be verified, expected data should be list of maps.
Please see the Script Assertion below:
assert context.response, 'Response is empty or null'
//list of maps; each map for single usage detail
//If the details are more, you may use a csv data file; solution may vary slightly
def expected = [
[ LimitCode: '022', LimitType: 'N', LimitPeriod: 1, LimitPeriodType: 'C'],
[ LimitCode: '023', LimitType: 'N', LimitPeriod: 3, LimitPeriodType: 'R']
]
 
 
def xml = new XmlSlurper().parseText(context.respone)
//Build the actual list of map from response
def actual = xml.'**'.findAll{it.name() == 'LimitAndUsageDetails'}.collect{ [
LimitCode : it.LimitCode.text(),
LimitType : it.LimitType.text(),
LimitPeriod : it.LimitPeriod.text() as Integer,
LimitPeriodType : it.LimitPeriodType.text()
]
}.sort {it.LimitCode}
assert expected == actual
You may quickly try the same online demo

You could use the below code which is also to get Response node values in
def groovyutils=new com.eviware.soapui.support.GroovyUtils(context)
def holder=groovyutils.getXmlHolder(messageExchange.responseContent)
holder.namespaces["ns"]="http://www.webserviceX.NET/"
def conversionRate=holder.getNodeValue("//ns:ConversionRateResult")
i was not able to test on your code since i dont have the correct namespace, but this code works perfectly fine for getting a value from response of currency convertor
you just need to change xpath inside getNodeValue and the namespace URL. this way its simpler

Related

How to get data from xml file using groovy?

Following groovy script is not working as expected.
def xml="<Collection><CustomerQuote><ID>99988877766</ID><TypeCode>2059</TypeCode><ApprovalStatusCode>4</ApprovalStatusCode></CustomerQuote><CustomerQuote><ID>99988877755</ID><TypeCode>2059</TypeCode><ApprovalStatusCode>4</ApprovalStatusCode></CustomerQuote></Collection>"
def completeXml= new XmlSlurper().parseText(xml);
def IDs = completeXml.Collection.CustomerQuote.findAll{node-> node.name() == 'ID' }*.text();
I am trying to copy all the ID value in xml in the IDs
Output
IDs[]
Expected Output
IDs[99988877766,99988877755]
I am not sure what i am doing wrong here.
Can anyone guide.
Thank you
Regards
Prat
The root node has to be omitted when using XmlSlurper, and you don't need to use findAll for this.
def xml="<Collection><CustomerQuote><ID>99988877766</ID><TypeCode>2059</TypeCode><ApprovalStatusCode>4</ApprovalStatusCode></CustomerQuote><CustomerQuote><ID>99988877755</ID><TypeCode>2059</TypeCode><ApprovalStatusCode>4</ApprovalStatusCode></CustomerQuote></Collection>"
def completeXml= new XmlSlurper().parseText(xml);
def IDs = completeXml.CustomerQuote.ID*.text();
Will output:
[
"99988877766",
"99988877755"
]
Try it in the Groovy Web Console

SOAPUI Square brackets around my actual results causing assert to fail

I am writing a Groovy script assertion which is verifying a value from a previous JDBC response step against a value contained in a SOAP response.
When I run my scripts I can see that both values are coming back the same but the actual result value (from the SOAP response) is surrounded by square brackets which in turn makes the assert fail. I'm guessing this is something to do with one being a string and one not?
How do I either strip out the square brackets from actual result or get them added to the expected result value to ensure the assert passes?
Below is my assert script.
Expected result is 001
Actual result is [001]
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def holder = groovyUtils.getXmlHolder( messageExchange.responseContent )
def pxml = new XmlSlurper().parseText(context.response)
//grab the expected result from jdbc response
def expectedCodes = context.expand( '${JDBC Request#ResponseAsXml#//*:TW304_PRODHIST.PRODUCT_1}' )
//grab the actual result from the SOAP response
def actualCodes = pxml.'**'.findAll{it.name() == 'CurrHospProductCode'}*.text()
assert expectedCodes == actualCodes
log.info expectedCodes
log.info actualCodes
Because you are expecting a single value as expected where as you are getting an array with single element in it.
You can do it as below if that is right :
assert expectedCodes == actualCodes[0]
On a side note, you may have to check carefully are you really expecting single value only or if there is possible to get list of values.
EDIT: based on your script.
findAll gives you list as result. If you are expecting single element in the xml, then you can change it to find and then you actual code should work as it is.

How to pick up child element of specific parent element in Script Assertion?

I have the following XML example which shows there are multiple occurrences of node 'ProductCode' which fall under both nodes 'PrevHospProduct' and also under 'PrevExtrasProducts'.
<ns2:PrevHospProducts>
<ns2:PrevHospProduct>
<ns2:ProductCode>D00</ns2:ProductCode>
<ns2:ExcessPaid>Yes</ns2:ExcessPaid>
</ns2:PrevHospProduct>
<ns2:PrevHospProduct>
<ns2:ProductCode>900</ns2:ProductCode>
</ns2:PrevHospProduct>
</ns2:PrevHospProducts>
<ns2:PrevExtrasProducts>
<ns2:PrevExtraProduct>
<ns2:ProductCode>00A</ns2:ProductCode>
</ns2:PrevExtraProduct>
</ns2:PrevExtrasProducts>
For this test I am only interested in the values in 'ProductCode' which are a child of 'PrevHospProduct'. I am not interested in any of the values under 'PrevExtrasProducts'.
I have the following Groovy Script Assertion in SoapUI to pick up values in 'ProductCode' but the test is failing as the actual results are also returning 'D00', '900' and '00A' from the examples response. I only want the expected results to pick values 'D00', '900'.
def expectedCodes = ['D00','900']
def pxml = new XmlSlurper().parseText(context.response)
def actualCodes = pxml.'**'.findAll{it.name() == 'ProductCode' }*.text() as List
assert expectedCodes.sort() == actualCodes.sort()
First need to find the parent node i.e., PrevHospProduct and then get the ProductCode.
Here is the script assertion:
def expectedCodes = ['D00','900']
def pxml = new XmlSlurper().parseText(context.response)
def actualCodes = pxml.'**'.findAll{it.name() == 'PrevHospProduct'}*.ProductCode*.text() as List
log.info actualCodes
assert expectedCodes.sort() == actualCodes.sort()

Assert multiple values in an XML response received on querying DB in SOAP UI

I am trying to retrieve some data from db and based on the response, I have to pass or fail a test case. I have to do this each time I query the db
I am able to make the connection to the db and get the response. However, not quite sure on how to assert the values from the response
Tried to use Script Assertion but not able to figure out as I am completely new at this
<Results>
<ResultSet fetchSize="10">
<Row rowNumber="1">
<T1>TEXT1</T1>
<T2>TASK1</T2>
<T3>Value1</T3>
<T4>xyz</T4>
</Row>
<Row rowNumber="2">
<T1>TEXT2</T1>
<T2>TASK2</T2>
<T3>Value1</T3>
<T4>ABC</T4>
</Row>
</ResultSet>
From the above response, on the first step I will have to assert that "TASK1" exists and the "Value1" exists with in the same set followed by the "TASK2" and "Value1"
Please let me know if this is vague so that I can try to modify my query
Use Xpath assertion instead
Assertion 1
/Results/ResultSet[#fetchSize="10"]/Row[1]/T1
Expected result
Task1
Assertion 2
/Results/ResultSet[#fetchSize="10"]/Row[1]/T3
Expected result
Value1
You can add as many Xpath Assertion as you want for any number of nodes.
Quick Tip: To generate XPaths use online tools or Oxygen XML Editor. :)
You can use Script Assertion for the JDBC Request test step in soapUI.
Script assertion
//define your expected data as map. You may add more key value pairs if more Rows
def expectedData = ['TASK1':'Value1', 'TASK2':'Value1']
//Assert if the response is not null
assert context.response, 'Response is not null or empty'
//Parse and get rows
def rows = new XmlSlurper().parseText(context.esponse).ResultSet.Row
def getRowData = { data, elementName, elementValue ->
data.'**'.findAll { it.name() == elementName && it == elementValue }*.parent()
}
def assertionErrors = new StringBuffer()
//Loop thur expectedData and capture the errors
expectedData.each { key, value->
def matchingRow = getRowData(rows, 'T2', key)[0]
value == matchingRow.T3.text() ?: assertionErrors.append("Assertion failed for rowNumber ${matchingRow.#rowNumber}\n")
}
//Check and show the result
if (assertionErrors) {
throw new Error(assertionErrors.toString())
} else {
log.info 'Assertions passed'
}
You may quickly try the solution online Demo; it shows how failure error message look like.
Note that, column names T2, T3are used in above script. If the names are different in original result, just make the change at your end.
Also note that assertion is not used deliberately to catch all the comparison issues, do not want to stop at first compare issue.
Try XmlSlurper: http://groovy-lang.org/processing-xml.html
To check TASK1:
def results = new XmlSlurper().parseText(response)
def row1 = results.ResultSet.find { node->
node.name() == 'Row' && node.#rowNumber == '1'
}
assert row1.T2 == 'TASK1'
I hope you'll be able to do the rest by your own ;)

using an assert with a contains in groovy

I am trying to run an assert with contains but am encountering an issue. I have written the code below using groovy in SOAPUI Pro
def pieceid = context.expand( '${OneDX#ResponseAsXml#//Results[1]/ResultSet[1]/Row[1]/PIECEID[1]}' )
def TrackingNumber = context.expand( '${OneDX#ResponseAsXml#//Results[1]/ResultSet[1]/Row[1]/TRACKINGNUMBER[1]}' )
assert {!TrackingNumber.contains(Pieceid)}
The tracking number is 907598985733 and Pieceid is 1820480....therefore the Pieceid is not in the tracking number. However when I run the script it passes. do you know what i'm doing wrong
Looks like a trivial issue in this case.
Changes:
replace ResponseAsXml with Response
removed { .. } in the assert statement, and introduced ( .. )
looks, you used incorrect variable i.e., Pieceid which is also not available - incorrect case.
Here is you go with the changed groovy script snippet:
def pieceid = context.expand( '${OneDX#Response#//Results[1]/ResultSet[1]/Row[1]/PIECEID[1]}' )
def trackingNumber = context.expand( '${OneDX#Response#//Results[1]/ResultSet[1]/Row[1]/TRACKINGNUMBER[1]}' )
log.info "Tracking number is $trackingNumber and Piece Id is $pieceid"
assert (!trackingNumber.contains(pieceid)), "Tracking number contains Pieceid"
You should be able to see the data of both variables in the log as well.
I would also like to recommend you not to use indexes in the xpath. Understand that might be auto generated by the tool. The reason being that if nodes come in different order, that will break your existing assertions for later test executions.

Resources