使用Groovy在SoapUI Pro中解析XML响应

时间:2013-12-23 14:16:36

标签: xml groovy soapui

我正在使用一个groovy脚本来验证对我的SoapUI xml请求的响应。

我有一个数据表,其中包含我的测试输入以及我想要在xml响应和预期结果中验证的元素的xpath。

xml element = // ns1:warningCode [1] 预期值= W0026

我的问题是,有时我的xml响应会返回除我要验证的警告代码之外的其他警告代码

e.g。我可能会将以下内容作为我的xml响应的一部分..

。 。 。

<NS1:departmentReference>200001060</NS1:departmentReference>
               <NS1:customerReference>invalid dept ref</NS1:customerReference>
               <NS1:senderReference>sendRef</NS1:senderReference>
            </NS1:requestedShipment>
         </NS1:completedShipmentInfo>
         <NS1:integrationFooter>
            <warnings xmlns="http://www.rmg.com/integration/core/V1">
               <warning>
                  <warningCode>W0022</warningCode>
                  <warningDescription>The customerReference specified is longer than 12 characters and has been truncated</warningDescription>
               </warning>
               <warning>
                  <warningCode>W0026</warningCode>
                  <warningDescription>The departmentReference specified is invalid and will be ignored</warningDescription>
               </warning>
            </warnings>

。 。

对于我的特定测试,我可能只想检查是否显示第二个警告。这意味着我需要a)要么确保我的测试数据不会产生任何其他警告消息,要么b)知道将返回多少警告消息以及它们将显示的顺序以便我的xpath正确。

我想知道如何重写我的脚本,以便在有任何包含我期望的代码的warningCode元素时它将被传递,无论它是第一个也是唯一的还是第三个warningCode元素。

这是我完整的groovy脚本验证...

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

def dataSource  = testRunner.testCase.getTestStepByName( "DataSourceShipmnt_v04" );

def groovyUtils     = new com.eviware.soapui.support.GroovyUtils(context);
def response        = context.expand( '${createShipmnt_v04#Response}' );     
def holder      = groovyUtils.getXmlHolder(response);   

//testElementOne will be something like '//ns1:warningCode[1]' or '//ns1:status/code'

def testElementOne = context.expand( '${DataSourceShipmnt_v04#testElement1}' ); 
def testElementTwo = context.expand( '${DataSourceShipmnt_v04#testElement2}' );

//expectedResp1 will be a warning code e.g W0026

def expectedResp1 = context.expand('${DataSourceShipmnt_v04#expectedResp1}');  
def expectedResp2 = context.expand( '${DataSourceShipmnt_v04#expectedResp2}'  ); 

def actRtrn1; 
def actRtrn2;

def result; //just a string value to return pass or fail.

try {

     actRtrn1       = holder.getNodeValue(testElementOne);
     actRtrn2       = holder.getNodeValue(testElementTwo);


}catch(Exception ex){}

if (  actRtrn1 == expectdResp1 && (actRtrn2 == expectdResp2 || actRtrn2 == null) ) {

  result = "pass";

} else {    

result = "fail";

}

非常感谢任何帮助。

感谢。担。

1 个答案:

答案 0 :(得分:2)

更简单的方法是使用XmlSlurper或XmlParser。下面我根据警告节点声明了命名空间(问题中提供的xml无效且不完整),您可以根据需要使用它:

def xml = '''
<warnings xmlns="http://www.rmg.com/integration/core/V1">
       <warning>
          <warningCode>W0022</warningCode>
          <warningDescription>The customerReference specified is 
             longer than 12 characters and has been
               truncated</warningDescription>
       </warning>
       <warning>
          <warningCode>W0026</warningCode>
          <warningDescription>The departmentReference specified is 
                         invalid and will be ignored</warningDescription>
       </warning>
</warnings>
'''

def expected = 'W0026'
def slurper = new XmlSlurper().parseText(xml)
            .declareNamespace('ns2': 'http://www.rmg.com/integration/core/V1')
assert expected in slurper.warning.warningCode.collect()*.toString()

上述断言确保在响应中获得的任何代码中都应存在预期的警告代码。