将JDBC响应与XML响应进行比较,其中节点数量变化且顺序可能会发生变化?

时间:2017-01-18 18:27:26

标签: xml groovy soapui

我对编码很陌生,在尝试将JDBC查询的结果与XML响应中的结果进行比较时遇到了一些麻烦。

我使用groovy而不是内置于SoapUI中的XPATH,因为基于我的请求中传递的参数,返回的节点数可能会有所不同,我需要验证所有这些节点。

我使用我发现的各种示例构建了下面的脚本,因为我找不到一个能够做我想要的示例。我插入了从类标记到eclipse的所有内容,它没有检测到任何语法错误。但是,当我在SoapUI中运行脚本时,当它到达解析xml响应的部分时,不会构建任何内容。然后我的验证和断言当然失败了。 JDBC数据构建得很好。

提前感谢您的任何帮助。

import com.eviware.soapui.support.XmlHolder
import groovy.xml.XmlUtil
import groovy.util.XmlSlurper
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)


class Model {
    def campaignSysKey
    def campaignName
    def startDate
    def endDate
    def campaignCode

    def buildJdbcData(row) {
        row.with {
            campaignSysKey = UPGRADETYPE
            campaignName = SOURCEDESC
            startDate = STARTDATE
            endDate = ENDDATE
            campaignCode = SOURCECODE
        }
    }

    def buildXMLData(tagInfo) {
        campaignSysKey = tagInfo.@campaignSysKey
        campaignName = tagInfo.@campaignName
        startDate = tagInfo.@startDate
        endDate = tagInfo.@endDate
        campaignCode = tagInfo.@campaignCode
    }
}

def jdbcResponse = context.expand('${Validation#ResponseAsXml}')
def xmlResponse = context.expand('${OfferHistoryRequest#Response}')

def results = new XmlSlurper().parseText(jdbcResponse)
def jdbcDataObjects = []
results.ResultSet.Row.each { row ->
    jdbcDataObjects.add(new Model().buildJdbcData(row))
}

def arrayOfTagInfo = new XmlSlurper().parseText(xmlResponse)
def xmlDataObjects = []
arrayOfTagInfo.TagInfo.each { tagInfo ->
    xmlDataObjects.add(new Model().buildXMLData(tagInfo))
}

log.info "${jdbcDataObjects.size()}"
log.info "${xmlDataObjects.size()}"


if (jdbcDataObjects.size() != xmlDataObjects.size()) {
    log.info("Jdbc resultset size is : ${jdbcDataObjects.size()} and XML result size is : ${xmlDataObjects.size()}")

}


assert jdbcDataObjects == xmlDataObjects, "Comparison of JDBC and XML data is failed"

JDBC响应结构:

<Results>
   <ResultSet fetchSize="0">
      <Row rowNumber="1">
         <UPGRADETYPE>1</UPGRADETYPE>
         <SOURCEDESC>Desc 1</SOURCEDESC>
         <STARTDATE>2015-01-01</STARTDATE>
         <ENDDATE>2017-12-31</ENDDATE>
         <SOURCECODE>ABC123</SOURCECODE>
      </Row>
      <Row rowNumber="2">
         <UPGRADETYPE>2</UPGRADETYPE>
         <SOURCEDESC>Desc 2</SOURCEDESC>
         <STARTDATE>2015-01-01</STARTDATE>
         <ENDDATE>2017-12-31</ENDDATE>
         <SOURCECODE>XYZ987</SOURCECODE>
      </Row>
   </ResultSet>
</Results>

XML响应(故意删除Holding标签之间的数据,但保留它们以显示响应结构。我只关注Campaign节点):

<soap:Envelope xmlns:soap="http://sample.org">
   <soap:Body>
      <TXLife xmlns="http://sample.org">
         <TXLifeResponse>
            <TransRefGUID>123456</TransRefGUID>
            <TransType tc="999"/>
            <TransSubType tc="9909"/>
            <BusinessService DataRep="VIEW"/>
            <TransExeDate>2017-01-19-05:00</TransExeDate>
            <TransExeTime>09:19:30.668-05:00</TransExeTime>
            <StartRecord>1</StartRecord>
            <TransResult>
               <ResultCode tc="1"/>
               <RecordsFound>2</RecordsFound>
            </TransResult>
            <OLifE>
               <Holding id="Holding_B1234567">                  
               </Holding>
               <Campaign id="Campaign_B1234567_1" AppliesToCoverageID="Coverage_B1234567_1">
                  <CampaignSysKey>1</CampaignSysKey>
                  <CampaignName>Desc 1</CampaignName>
                  <StartDate>2015-01-01</StartDate>
                  <EndDate>2017-12-31</EndDate>
                  <CampaignCode>ABC123</CampaignCode>
               </Campaign>
               <Campaign id="Campaign_B1234567_2" AppliesToCoverageID="Coverage_B1234567_2">
                  <CampaignSysKey>2</CampaignSysKey>
                  <CampaignName>Desc 2</CampaignName>
                  <StartDate>2015-01-01</StartDate>
                  <EndDate>2017-12-31</EndDate>
                  <CampaignCode>XYZ987</CampaignCode>
               </Campaign>
            </OLifE>
         </TXLifeResponse>
      </TXLife>
   </soap:Body>
</soap:Envelope>

SoapUI日志错误:

Thu Jan 19 10:00:31 EST 2017:ERROR:java.lang.AssertionError: Comparison of JDBC and XML data is failed. Expression: (jdbcDataObjects == xmlDataObjects). Values: jdbcDataObjects = [X34143, X33582], xmlDataObjects = []
   java.lang.AssertionError: Comparison of JDBC and XML data is failed. Expression: (jdbcDataObjects == xmlDataObjects). Values: jdbcDataObjects = [X34143, X33582], xmlDataObjects = []
    at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:404)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:650)
    at Script5.run(Script5.groovy:67)
    at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:92)
    at com.eviware.soapui.support.scripting.groovy.SoapUIProGroovyScriptEngineFactory$SoapUIProGroovyScriptEngine.run(SoapUIProGroovyScriptEngineFactory.java:79)
    at com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep.run(WsdlGroovyScriptTestStep.java:156)
    at com.eviware.soapui.impl.wsdl.panels.teststeps.GroovyScriptStepDesktopPanel$RunAction$1.run(GroovyScriptStepDesktopPanel.java:274)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

1 个答案:

答案 0 :(得分:0)

以下是我更正的脚本以使其正常工作。

您编写和解决的脚本中的问题如下 -

  • xml元素未正确读取
  • 使方法成为静态
  • 将规范注释添加到类中以便它可以进行比较

Groovy脚本

//Class to model the different sources of data and create object
//so that those are comparable
@groovy.transform.Canonical
class Model {
    String campaignSysKey
    String campaignName
    String startDate
    String endDate
    String campaignCode

    static def buildJdbcData(row) {
        def obj = new Model()
        row.with {
            obj.campaignSysKey = UPGRADETYPE
            obj.campaignName = SOURCEDESC
            obj.startDate = STARTDATE
            obj.endDate = ENDDATE
            obj.campaignCode = SOURCECODE
        }
        obj
    }

    static def buildXMLData(cmpgn) {
        def obj = new Model()
        obj.campaignSysKey = cmpgn.CampaignSysKey as String
        obj.campaignName = cmpgn.CampaignName as String
        obj.startDate = cmpgn.StartDate as String
        obj.endDate = cmpgn.EndDate as String
        obj.campaignCode = cmpgn.CampaignCode as String
        obj
    }
}

//Read the jdbc response from its step 
def jdbcResponse = context.expand('${Validation#ResponseAsXml}')

//Read the xml response from its step
def xmlResponse = context.expand('${OfferHistoryRequest#Response}')

//Read & Create objects for jdbc response
def results = new XmlSlurper().parseText(jdbcResponse)
def jdbcDataObjects = []
results.ResultSet.Row.each { row ->
    jdbcDataObjects.add(Model.buildJdbcData(row))
}

//Read & Create objects for xml response
def parsedXml = new XmlSlurper().parseText(xmlResponse)
def campaigns = parsedXml.'**'.findAll{it.name() == 'Campaign'}
def xmlDataObjects = []
campaigns.each { cmpgn ->
    xmlDataObjects.add(Model.buildXMLData(cmpgn))
}

//Log both responses
log.info "Jdbc response records: ${jdbcDataObjects.size()}"
log.info "Xml response records: ${xmlDataObjects.size()}"


if (jdbcDataObjects.size() != xmlDataObjects.size()) {
    log.info("Jdbc resultset size is : ${jdbcDataObjects.size()} and XML result size is : ${xmlDataObjects.size()}") 
}

//Check if both object sizes are equal before comparing one to one
assert jdbcDataObjects.size() == xmlDataObjects.size(), "Both responses have not matched element count"

//Log both the objects
log.info jdbcDataObjects.toString()
log.info xmlDataObjects.toString()

//Compare now both the responses and show the difference
if (jdbcDataObjects != xmlDataObjects){
    log.info "Both responses do not match"
    for(int index=0;index<jdbcDataObjects.size();index++){
        assert jdbcDataObjects[index] == xmlDataObjects[index], "Responses @ ${index+1} position do not match"
    }
} else {
    log.info "Both responses matches"
}

顺便说一下,您发布的回复有差异。

如果您想快速查看在线demo