繁体   English   中英

Groovy脚本断言可验证XML中的属性对脚本中CSV文件中的值的响应

[英]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>

我在想一种解决方案的思路是:

  • 计算响应中订阅者元素的数量。 与csv / testcase属性中的非空值数量进行比较。 如果不相等,则立即失败。
  • 对于每个externalId属性,将其与csv / testcase属性中的所有非空值进行比较(如果存在匹配项),请将计数器(props / csv中的非空数)减少1。 如果在所有比较结束时计数器不等于零,则失败。 否则,脚本断言将通过。

不幸的是,我对Groovy和SoapUI还是陌生的,我不确定如何真正实现这一点,因此,如果有人有任何想法或技巧,将不胜感激!

我建议另一种选择:

  1. 从Web服务中将所有Subscriber externalId属性读取到一个String列表中并对该列表进行排序。
  2. 将所有CSV值读取到字符串列表中并对该列表进行排序。
  3. 断言两个列表相同。

您可以使用此示例作为基础。 您要做的是:

  1. 更换XmlSlurper.parseText()XmlSlurper.parse()使用Web服务的URI。
  2. 我看不到将static externalId列表保留为CSV文件的任何价值。 相反,我使用了一个简单的文件,其中的每一行都包含一个externalId(没有逗号分隔)。 相反,使用CSV应该相当容易。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM