groovysoapuiassertiongroovyscriptengine

What is the right way to compare two strings in SoapUI with groovy script assertion?


I need to compare two strings in SoapUI. The first one is from a text file stored in my local directory, and the second one is from an XML response I get from a REST API operation. Before comparing the two strings, I use some methods on them to remove the header because they contain information like Dates and Processing Time which is sure to be different each time.

Below is what I've tried.

def xml = messageExchange.responseContentAsXml
String fileData = new File("C://Users/362784/project/outputPGB123.txt").text

String responseContent = new XmlSlurper().parseText(xml)

String fileDataFiltered = fileData.substring(fileData.indexOf("PASSED :"))
String responseContentFiltered = responseContent.substring(responseContent.indexOf("PASSED :"))

log.info(fileDataFiltered)
log.info(responseContentFiltered)

assert fileDataFiltered == responseContentFiltered

Here is the error I received

SoapUI error message

and my two identical log.info

log.info

Here's what the XML response looks like

I am new to SoapUI and I'm not sure what those two are actually comparing but I've checked the log.info of them on https://www.diffchecker.com/diff and the contents are identical. However, this assertion returns an error.

Can anyone point out what I did wrong and how do I get the result as passed?


Solution

  • In Java/Groovy you compare string values for equality like this:

    assert fileDataFiltered.equals(responseContentFiltered)
    

    See if that solves your problem.

    The == comparator could, for example, compare object instances which could fail even if the text values are identical. See here for a more in-depth explanation.

    EDIT:

    Having seen your sample, it looks like the value you are comparing is inside XML character data (CDATA).

    Consider the following example from here:

    Some XML:

    def response = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:sam="http://www.example.org/sample/">
       <soapenv:Header/>
       <soapenv:Body>
          <sam:searchResponse>
             <sam:searchResponse>
                <item><id>1234</id><description><![CDATA[<item><width>123</width><height>345</height><length>098</length><isle>A34</isle></item>]]></description><price>123</price>
                </item>
             </sam:searchResponse>
          </sam:searchResponse>
       </soapenv:Body>
    </soapenv:Envelope>
    '''
    

    Then access the CDATA node with XmlSlurper:

    def Envelope = new XmlSlurper().parseText(response)
    def cdata = Envelope.Body.searchResponse.searchResponse.item.description
    log.info cdata
    log.info cdata.getClass()
    assert cdata instanceof groovy.util.slurpersupport.NodeChildren
    

    As you can see, the value returned is of object NodeChildren. You can convert it to a string with:

    log.info cdata.toString()
    log.info cdata.toString().getClass()
    

    So let's do a comparison (as per cfrick's comment, you can use == or .equals())

    def expectedCdata = '<item><width>123</width><height>345</height>length>098</length><isle>A34</isle></item>'
    
    if (cdata.toString().equals(expectedCdata)) { log.info 'Equal' }
    else {log.info 'Different'}
    

    It still fails ???

    Well, that is because of a residual newline that isn't obvious from printing with log.info, if you remove whitespace it works in this case:

    if (cdata.toString().replaceAll("\\s","").equals(expectedCdata)) { log.info 'Equal' }
    else {log.info 'Different'}
    

    As you can see, there are many levels of possible failure. You have to work through it.