Groovy SOAP UI XML 响应中 Key/Value 对的脚本断言

Groovy Script assert on Key/Value pairs in SOAP UI XML response

我正在使用就绪 API/SOAP UI。我添加了一个 SOAP 请求并得到了一个 SOAP 响应 XML。我的响应对象最多有 40 Key/Value 对。

我有专门测试每一个的功能测试。

我能为这种情况找到可行的解决方案吗?我无法对输出对象进行断言。

SOAP 结构如下所示:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>  
     <ArrayOfallObjects>
       <ArrayOfObjects>
          <Key>Key1</Key>
          <Value>Value1</Value>
       </ArrayOfObjects>
       <ArrayOfObjects>
          <Key>Key2</Key>
          <Value>Value2</Value>
       </ArrayOfObjects>
       ---------------
       <ArrayOfObjects>
          <Key>Key40</Key>
          <Value>Value40</Value>
       </ArrayOfObjects>
     </ArrayOfallObjects>   
   </soap:Body>
</soap:Envelope>

我正在使用 groovy 脚本片段如下

//Code Snippet Starts//    
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)    
def request = context.testCase.getTestStepByName("RequestName")    
def responseCurrentHolder = groovyUtils.getXmlHolder( request.name +"#Response")
responseCurrentHolder.namespaces["ns1"] = "https://test.com"
def nodes = responseCurrentHolder.getDomNodes( "//ns1:Response/ns1:Result/ns1:ArrayOfallObjects/ns1:ArrayOfObject/*" )
def nodeCount = responseCurrentHolder.getNodeValues("//ns1:Response/ns1:Result/ns1:ArrayOfallObjects/ns1:ArrayOfObject/ns1:Key").length

def object = [:]
for (def nodeIndex = 1; nodeIndex <= nodeCount; nodeIndex++) {    
def nodeKey = responseCurrentHolder.getNodeValues("//ns1:Response/ns1:Result/ns1:ArrayOfallObjects/ns1:ArrayOfObject[$nodeIndex]/ns1:Key/text()")    
def nodeValue = responseCurrentHolder.getNodeValue("//ns1:Response/ns1:Result/ns1:ArrayOfallObjects/ns1:ArrayOfObject[$nodeIndex]/ns1:Value/text()")

  object.put( nodeKey,nodeValue)
}
log.info "Object =" +object

// Code snippet ends//

对象看起来像:

Object =[[Key1]:Value1, [Key2]:Value2, and so on upto --,[Key40]:Value40]

您可以对相同的 soap 请求测试步骤使用 Script Assertion 来验证相同的内容,而无需添加额外的 Groovy Script 测试步骤。

不确定上述示例是否具有相同的 xml 结构(如果不完全相同)。否则,请根据您的需要进行更改。

方法如下:

  • 由于要验证的数据比较复杂,而且有key、value pattern;因此,将地图定义为您上次指出的预期数据。
  • 阅读 xml 回复,并从中创建类似的地图。有时,可能需要按键(或基于数据的其他标准)对检索到的数据进行排序。
  • 然后检查预期数据和实际数据。

脚本断言:

//Define expected data; using few elements as sample
def expectedMap = [Key1: 'Value1', Key2: 'Value2', Key40: 'Value40']

//Check if there is response
assert context.response, 'Response is empty or null'

//Parse the response
def xml = new XmlSlurper().parseText(context.response)

//Extract the data, create actual map and sort by key
def actualMap = xml.'**'.findAll {it.name() == 'ArrayOfObjects' }.collectEntries {[(it.Key.text()): it.Value.text()]}​?.sort {it.key}
log.info actualMap
assert expectedMap == actualMap

您可以快速在线试用demo

下面的代码首先获取一个数组(x)中的所有键和另一个数组中的所有值 y(x)。如果没有,您可以将它们添加到地图中,您可以直接断言值

下面是验证键值对的最简单的方法之一

只需将 'First Step' 替换为生成响应的步骤的名称

def groovyUtils = new  com.eviware.soapui.support.GroovyUtils(context)

def response = groovyUtils.getXmlHolder("First Step#Response")

def x = response.getNodeValues("//*[local-name()='ArrayOfObjects']//*[local-name()='Key']")
for ( def keys in x)
{
log.info keys
}
 def y = response.getNodeValues("//*[local-name()='ArrayOfObjects']//*[local-name()='Value']")
for ( def values in y)
 {
log.info values
}

log.info "total keys are " + x.size()

for(int i = 0 ; i < x.size() ; i++)
{
 log.info " key = " + x[i] + " Value = " + y[i] 
}

这是我运行上述脚本

时的结果

10 月 28 日星期六 14:41:57 IST 2017:INFO:Key1

10 月 28 日星期六 14:41:57 IST 2017:INFO:Key2

10 月 28 日星期六 14:41:57 IST 2017:INFO:Key40

10 月 28 日星期六 14:41:57 IST 2017:INFO:Value1

10 月 28 日星期六 14:41:57 IST 2017:INFO:Value2

10 月 28 日星期六 14:41:57 IST 2017:INFO:Value40

10 月 28 日星期六 14:41:57 IST 2017:INFO:total 键是 3

10 月 28 日星期六 14:41:57 IST 2017:INFO:key = Key1 Value = Value1

10 月 28 日星期六 14:41:57 IST 2017:INFO:key = Key2 Value = Value2

10 月 28 日星期六 14:41:57 IST 2017:INFO:key = Key40 Value = Value40