[英]Groovy script assertion to verify attributes in XML response to values in CSV file in script
我目前正在使用SoapUI根据从另一个脚本中的CSV文件中提取的值来调用Web服务( 位于此处,供那些感兴趣的人使用 )。 我想做的是解析该webservice调用的响应,以验证每个Subscriber元素的externalId
值是否与CSV文件中的externalId
值匹配(该值通过其他脚本保存在测试用例属性中),并且没有任何额外/更少的退货。
肥皂响应的示例如下。
<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还是陌生的,我不确定如何真正实现这一点,因此,如果有人有任何想法或技巧,将不胜感激!
我建议另一种选择:
您可以使用此示例作为基础。 您要做的是:
XmlSlurper.parseText()
与XmlSlurper.parse()
使用Web服务的URI。 XML作为字符串:
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
我故意加扰了ID。 我称它为ids.csv
,尽管它当然不是CSV文件。
将文件行读入(隐式)String列表中并进行排序:
def idsFromFiles = new File("ids.csv").readLines()*.trim().sort()
*
是传播运算符,表示使用readLines()
读取的列表中的每个项目都会被修剪(如果文件行没有空格,则不会修剪)。
最后,比较两个列表以确认它们包含相同的项目:
assert idsFromSoap == idsFromFiles
编辑
关于您的评论:是的。 parse(String)
接受有效的URL(例如ws.web.blah.com)并解析响应,只要响应是有效的XML / XHTML。 因此,您可以完全跳过使用SOAP UI的过程,而仅调用URL。
如何在不处理上下文变量的情况下获得整个响应?
它与SOAP UI上下文完全无关。
至于SOAP UI,我对API并不熟悉。 但是只要您可以将响应保存到String(或File / Stream并使用重载的parse()
方法),代码就应该可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.