0

I've upgraded to SoapUI Pro (ReadyAPI) recently and I've come across the following problem. I have an XPath assertion like this:

declare namespace ns2='http://some.schema.tld/foo/bar/1.0';//ns2:GenerateOrResetPasswordFault//faultCode

it's matched against a specific value which I get in the faultCode element. I however get two of these in the same parent, so the response contains something like

//..
<GenerateOrResetPasswordFault>
    <faultCode>123</faultCode>
    <faultCode>456</faultCode>
</GenerateOrResetPasswordFault>
//...

I previously had two assertions, one matched against 123 and the other, same XPath, matched against 456 and it worked. Now after switching the assertion fails because the XPath actually returns [123,456] as a result.

What is the best way to handle this, please?

Rao
  • 20,781
  • 11
  • 57
  • 77
Dropout
  • 13,653
  • 10
  • 56
  • 109
  • Is it not allowing to assert a list then? – Rao Nov 21 '17 at 19:40
  • @Rao It is, but I cannot rely on the list being in the same order unfortunately. Is it possible to do an assertion which lists out the elements, but isn't a literal comparison? – Dropout Nov 22 '17 at 08:17
  • 1
    Then you can use script assertion. Are you ok with that? – Rao Nov 22 '17 at 09:39
  • @Rao if that's the only option, then I got no other choice. I'll have to forward this to some of our testers who are not so keen on scripting, which is a bit of an issue, so I was trying to find a simpler solution. I'm just surprised that it's actually more complicated than it was in SoapUI – Dropout Nov 22 '17 at 10:35
  • 1
    Dropout, please check the solution to see if that helps. – Rao Nov 22 '17 at 17:18
  • @Rao thank you, nice idea! – Dropout Nov 23 '17 at 09:18

1 Answers1

2

Here is the Script Assertion to achieve the same. This way, you need not to have multiple xpath assertions as well.

Script Assertion: follow in-line comments

//Check if the response is ok
assert context.response, 'Response is empty or null'

//Define your expected fault codes
def expectedCodes = [123, 456]


def actualCodes = []
if (context.response.contains('faultCode')) {
  //Get the actual fault codes from xml response by parse and find 
  actualCodes = new XmlSlurper().parseText(context.response).'**'.findAll {it.name() == 'faultCode' }*.text() as Integer[]
  log.info "Actual fault codes are : ${actualCodes}"

  //Check both expected and actual are matching
  assert expectedCodes.sort() == actualCodes.sort()
} else {
  throw new Error('Response does not contain faultCode elements')
}

You can quickly try it on-line demo for the given xml data.

Rao
  • 20,781
  • 11
  • 57
  • 77