我目前正在使用SoapUI根据我在另一个脚本(Located here for those interested)中从我的CSV文件中提取的值来调用Web服务。我要做的是解析该webservice调用的响应,以验证每个Subscriber元素的externalId
值是否与CSV文件中的值匹配(通过以下方式保存在测试用例属性中)其他脚本),并且没有任何额外/更少的返回。
肥皂反应的一个例子见下文。
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<ws:searchResponse xmlns:ws="http://ws.web.blah.com">
<result dataUpdated="false">
<Subscriber lastReportDate="2014-05-28T11:00:02-03:00" externalId="20107A-R29O12KH11113233" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="803227" macAddress="D2:9F:EE:11:32:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber ip="11.13.23.33" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132333" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101553" macAddress="AB:CD:11:13:23:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber ip="11.13.23.32" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132332" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101550" macAddress="AB:CD:11:13:23:32" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber ip="11.13.23.31" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132331" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101545" macAddress="AB:CD:11:13:23:31" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber ip="11.13.23.23" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132323" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101542" macAddress="AB:CD:11:13:23:23" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber ip="11.13.23.22" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132322" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101537" macAddress="AB:CD:11:13:23:22" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber ip="11.13.23.21" lastReportDate="2014-05-28T12:07:16.998-03:00" externalId="12345678-1234-ABCD-ABCD-ABCD11132321" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="101533" macAddress="AB:CD:11:13:23:21" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber externalId="32321070" neighborhoodID="103290" neighborhood="PMBKXXDSL11" city="TORO" nodeId="100942" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber externalId="PMBKONOLT11:3-2-3-2-1070" neighborhoodID="103290" neighborhood="PMBKXXDSL11" city="TORO" nodeId="100941" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber lastReportDate="2014-05-28T12:00:01-03:00" externalId="001404-D29247113233" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="100716" macAddress="D2:9D:CC:11:32:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
<Subscriber lastReportDate="2014-05-28T12:00:01-03:00" externalId="001A73-WECO10KH11113233" classification="noerror" neighborhoodID="103280" neighborhood="PMBKONOLT11" city="TORO" nodeId="100414" macAddress="D2:9A:BB:11:32:33" lastName="first2047 last2047" phoneNumber="5068880029" subscriberId="100107"/>
</result>
</ws:searchResponse>
</env:Body>
</env:Envelope>
我想要解决的问题是:
externalId
属性,与csv / testcase属性中的所有非空值进行比较,如果匹配,则将计数器(props / csv中的非空值数)减1。如果在所有比较结束时计数器不等于零,则失败。否则脚本断言就会通过。不幸的是,我对Groovy和SoapUI非常陌生,而且我不确定如何真正实现这一点,所以如果有任何想法或提示,我们将不胜感激!
答案 0 :(得分:2)
我建议另一种选择:
您可以使用此示例作为基础。你还要做的是:
XmlSlurper.parseText()
替换为XmlSlurper.parse()
。XML as String:
def xml = "<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <env:Header/>\n" +
" <env:Body>\n" +
" <ws:searchResponse xmlns:ws=\"http://ws.web.blah.com\">\n" +
" <result dataUpdated=\"false\">\n" +
" <Subscriber lastReportDate=\"2014-05-28T11:00:02-03:00\" externalId=\"20107A-R29O12KH11113233\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"803227\" macAddress=\"D2:9F:EE:11:32:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber ip=\"11.13.23.33\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132333\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101553\" macAddress=\"AB:CD:11:13:23:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber ip=\"11.13.23.32\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132332\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101550\" macAddress=\"AB:CD:11:13:23:32\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber ip=\"11.13.23.31\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132331\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101545\" macAddress=\"AB:CD:11:13:23:31\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber ip=\"11.13.23.23\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132323\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101542\" macAddress=\"AB:CD:11:13:23:23\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber ip=\"11.13.23.22\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132322\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101537\" macAddress=\"AB:CD:11:13:23:22\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber ip=\"11.13.23.21\" lastReportDate=\"2014-05-28T12:07:16.998-03:00\" externalId=\"12345678-1234-ABCD-ABCD-ABCD11132321\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"101533\" macAddress=\"AB:CD:11:13:23:21\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber externalId=\"32321070\" neighborhoodID=\"103290\" neighborhood=\"PMBKXXDSL11\" city=\"TORO\" nodeId=\"100942\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber externalId=\"PMBKONOLT11:3-2-3-2-1070\" neighborhoodID=\"103290\" neighborhood=\"PMBKXXDSL11\" city=\"TORO\" nodeId=\"100941\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber lastReportDate=\"2014-05-28T12:00:01-03:00\" externalId=\"001404-D29247113233\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"100716\" macAddress=\"D2:9D:CC:11:32:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" <Subscriber lastReportDate=\"2014-05-28T12:00:01-03:00\" externalId=\"001A73-WECO10KH11113233\" classification=\"noerror\" neighborhoodID=\"103280\" neighborhood=\"PMBKONOLT11\" city=\"TORO\" nodeId=\"100414\" macAddress=\"D2:9A:BB:11:32:33\" lastName=\"first2047 last2047\" phoneNumber=\"5068880029\" subscriberId=\"100107\"/>\n" +
" </result>\n" +
" </ws:searchResponse>\n" +
" </env:Body>\n" +
"</env:Envelope>"
检索订户节点列表:
def subscribers = new XmlSlurper(false, true).parseText(xml).Body.searchResponse.result.Subscriber
// Replace parseText with parse(uri)
将XML Subscriber元素转换为String:
列表 def idsFromSoap = subscribers.collect{it.@externalId.text()}.sort()
collect()
方法通过it.@externalId.text()
将订阅者节点转换为(externalId属性)字符串列表。然后对转换后的String列表进行排序。
现在,创建一个包含以下内容的文件:
12345678-1234-ABCD-ABCD-ABCD11132321
001404-D29247113233
001A73-WECO10KH11113233
12345678-1234-ABCD-ABCD-ABCD11132322
PMBKONOLT11:3-2-3-2-1070
12345678-1234-ABCD-ABCD-ABCD11132323
32321070
12345678-1234-ABCD-ABCD-ABCD11132333
20107A-R29O12KH11113233
12345678-1234-ABCD-ABCD-ABCD11132331
12345678-1234-ABCD-ABCD-ABCD11132332
我故意扰乱了这些ids。我称之为ids.csv
,即使它当然不是CSV文件。
将文件行读入(隐含)String列表并排序:
def idsFromFiles = new File("ids.csv").readLines()*.trim().sort()
*
是扩展运算符,意味着使用readLines()
读取的列表中的每个项都被修剪(如果文件行没有空格,则没有修剪)。
最后,比较两个列表以验证它们包含相同的项目:
assert idsFromSoap == idsFromFiles
修改强>
关于你的意见:
是。只要响应是有效的XML / XHTML,parse(String)
就会接受有效的URL,例如ws.web.blah.com并解析响应。因此,您可以完全跳过使用SOAP UI,只需调用URL。
如何在不处理上下文变量的情况下获得整个响应?
它根本与SOAP UI上下文无关。
对于SOAP UI,我不熟悉API。但只要您可以将响应保存到String(或文件/流并使用重载的parse()
方法),代码就可以工作。