简体   繁体   English

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

[英]Groovy script assertion to verify attributes in XML response to values in CSV file in script

I'm currently using SoapUI to make a call to a webservice based on a value I've pulled from my CSV file in another script ( Located here for those interested ). 我目前正在使用SoapUI根据从另一个脚本中的CSV文件中提取的值来调用Web服务( 位于此处,供那些感兴趣的人使用 )。 What I'd like to do is parse the response of that webservice call to verify that the externalId values for every Subscriber element match the ones in the CSV file (which are are saved in the test case properties via the other script), and that there aren't any extra/less being returned. 我想做的是解析该webservice调用的响应,以验证每个Subscriber元素的externalId值是否与CSV文件中的externalId值匹配(该值通过其他脚本保存在测试用例属性中),并且没有任何额外/更少的退货。

An example of the soap response is seen below. 肥皂响应的示例如下。

<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>

What I was thinking for a solution would be something along the lines of: 我在想一种解决方案的思路是:

  • Count the number of subscriber elements in the response. 计算响应中订阅者元素的数量。 Compare with number of non-null values in the csv/testcase properties. 与csv / testcase属性中的非空值数量进行比较。 If not equal, immediately fail. 如果不相等,则立即失败。
  • For every externalId attribute, compare with all non-null values in csv/testcase properties, if there's a match, decrease a counter(number of non-nulls in props/csv) by one. 对于每个externalId属性,将其与csv / testcase属性中的所有非空值进行比较(如果存在匹配项),请将计数器(props / csv中的非空数)减少1。 If by the end of all the compares the counter doesn't equal zero, then fail. 如果在所有比较结束时计数器不等于零,则失败。 Otherwise the script assertion passes. 否则,脚本断言将通过。

Unfortunately I'm very new to Groovy and SoapUI, and I'm unsure of how to really implement this, so if anyone has any ideas or tips it would be greatly appreciated! 不幸的是,我对Groovy和SoapUI还是陌生的,我不确定如何真正实现这一点,因此,如果有人有任何想法或技巧,将不胜感激!

I suggest another alternative: 我建议另一种选择:

  1. Read all Subscriber externalId attributes from the Web Service into a String list and sort the list. 从Web服务中将所有Subscriber externalId属性读取到一个String列表中并对该列表进行排序。
  2. Read all CSV values into a String list and sort the list. 将所有CSV值读取到字符串列表中并对该列表进行排序。
  3. Assert the two lists are same. 断言两个列表相同。

You can use this example as a basis. 您可以使用此示例作为基础。 What you are left to do is: 您要做的是:

  1. Replace the XmlSlurper.parseText() with XmlSlurper.parse() using the Web Service URI. 更换XmlSlurper.parseText()XmlSlurper.parse()使用Web服务的URI。
  2. I don't see any value in keeping the static externalId list as a CSV file. 我看不到将static externalId列表保留为CSV文件的任何价值。 Instead I've used a simple file where each line contains an externalId (no comma separated). 相反,我使用了一个简单的文件,其中的每一行都包含一个externalId(没有逗号分隔)。 Using CSV instead should be fairly easy. 相反,使用CSV应该相当容易。

The XML as String: 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>"

Retrieve the subscribers node list: 检索订户节点列表:

def subscribers = new XmlSlurper(false, true).parseText(xml).Body.searchResponse.result.Subscriber
// Replace parseText with parse(uri)

Transform the XML Subscriber elements into a list of String: 将XML Subscriber元素转换为String列表:

def idsFromSoap = subscribers.collect{it.@externalId.text()}.sort()

The collect() method transforms Subscriber nodes into a list of (externalId attribute ) String via it.@externalId.text() . collect()方法通过it.@externalId.text()将订户节点转换为(externalId属性)String的列表。 The transformed String list is then sorted. 然后对转换后的字符串列表进行排序。

Now, create a file with the following content: 现在,创建一个具有以下内容的文件:

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

I've scrambled the ids on purpose. 我故意加扰了ID。 I've called it ids.csv even though it's not a CSV file of course. 我称它为ids.csv ,尽管它当然不是CSV文件。

Read the file lines into (implicit) list of String and sort: 将文件行读入(隐式)String列表中并进行排序:

def idsFromFiles = new File("ids.csv").readLines()*.trim().sort()

* is the spread operator meaning every item in the list read using readLines() is trimmed (you don't have trim if the file lines are kept with no spaces). *是传播运算符,表示使用readLines()读取的列表中的每个项目都会被修剪(如果文件行没有空格,则不会修剪)。

Finally, compare the two lists to verify they contain the same items: 最后,比较两个列表以确认它们包含相同的项目:

assert idsFromSoap == idsFromFiles

EDIT 编辑

As to your comments: Yes. 关于您的评论:是的。 parse(String) accepts a valid URL such as ws.web.blah.com and parses the response, as long as the response is a valid XML/XHTML. parse(String)接受有效的URL(例如ws.web.blah.com)并解析响应,只要响应是有效的XML / XHTML。 So you can skip using SOAP UI altogether, and just invoke the URL. 因此,您可以完全跳过使用SOAP UI的过程,而仅调用URL。

how does that get the entire response without dealing with the context variable? 如何在不处理上下文变量的情况下获得整个响应?

It has nothing to do with SOAP UI context at all. 它与SOAP UI上下文完全无关。

As for SOAP UI, I'm not familiar with the API. 至于SOAP UI,我对API并不熟悉。 But as long as you can save the response to a String (or File/Stream and use the overloaded parse() methods), the code should work. 但是只要您可以将响应保存到String(或File / Stream并使用重载的parse()方法),代码就应该可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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