在SoapUI中使用groovy数组动态比较Rest XML / JSON响应和JDBC

时间:2015-07-17 09:20:15

标签: json xml rest groovy soapui

在SoapUI中,我有一个JDBC测试步骤,它返回以下数据:

<Results>
<ResultSet fetchSize="128">
    <Row rowNumber="1">
        <ID>1</ID>
        <NAME>TestName1</NAME>
        <DESCRIPTION/>
        <TYPE>Bool</TYPE>
        <ISPRODUCTTAG>true</ISPRODUCTTAG>
        <ISLOCATIONTAG>false</ISLOCATIONTAG>
        <SUBSECTION>Default Sub Section</SUBSECTION>
        <SECTION>Default Section</SECTION>
        <SUBGROUP>Default Sub Group</SUBGROUP>
        <GROUP>Default Group</GROUP>
    </Row>
    <Row rowNumber="2">
        <ID>2</ID>
        <NAME>TestName2</NAME>
        <DESCRIPTION/>
        <TYPE>Bool</TYPE>
        <ISPRODUCTTAG>true</ISPRODUCTTAG>
        <ISLOCATIONTAG>false</ISLOCATIONTAG>
        <SUBSECTION>Default Sub Section</SUBSECTION>
        <SECTION>Default Section</SECTION>
        <SUBGROUP>Default Sub Group</SUBGROUP>
        <GROUP>Default Group</GROUP>
    </Row>
    </Row>
</ResultSet>

我有一个包含以下数据的REST API XML响应:

    <ArrayOfTagInfo>
   <TagInfo id="1" name="TestName1" type="Bool" isProductTag="true" isLocationTag="false" subsection="Default Sub Section" section="Default Section" subgroup="Default Sub Group" group="Default Group"/>
   <TagInfo id="2" name="TestName2" type="Bool" isProductTag="true" isLocationTag="false" subsection="Default Sub Section" section="Default Section" subgroup="Default Sub Group" group="Default Group"/>
</ArrayOfTagInfo>

我希望能够使用groovy数组比较(断言)数据库值和响应值(响应可以是XML或JSON,具体取决于Request Accept Header),因为从数据库返回的数据可以非常大。

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

如果你有SoapUI-Pro,你应该能够在没有Groovy的情况下完成所有这些。

  1. 进行REST调用以检索所有数据。
  2. 启动解析XML的DataSource step
  3. 进行JDBC调用,选择要验证的行的正确ID。在这里做所有的断言。
  4. 循环回#2。

答案 1 :(得分:0)

您可以使用以下测试步骤设计测试用例:

  1. jdbc step
  2. json step
  3. groovy script step
  4. groovy脚本步骤中的想法/ sudo代码是

    • 获取jdbc步骤的响应
    • 得到json step的回复
    • 以对象的形式构建数据,以便于比较
    • 将对象存储在列表中,一个用于jdbc,另一个用于json
    • 对两个列表进行排序,以确保比较相同的数据
    • 比较两个列表是否相同。

    这里是groovy脚本:

    /**
     * Model object for comparing
     */
    @groovy.transform.Canonical
    class Model {
        def id
        def name
        def type
        def isProductTag
        def isLocationTag
        def subSection
        def section
        def subGroup
        def group
    
        /**
         * this will acception jdbc row
         * @param row
         * @return
         */
        def buildJdbcData(row) {
            row.with {
                id = ID
                name = NAME
                type = TYPE
                isProductTag = ISPRODUCTTAG
                isLocationTag = ISLOCATIONTAG
                subSection = SUBSECTION
                section = SECTION
                subGroup = SUBGROUP
                group = GROUP
            }
        }
    
        /**
         * this will accept the json TagInfo
         * @param tagInfo
         * @return
         */
        def buildJsonData(tagInfo){
            id = tagInfo.@id
            name = tagInfo.@name
            type = tagInfo.@type
            isProductTag = tagInfo.@isProductTag
            isLocationTag = tagInfo.@isLocationTag
            subSection = tagInfo.@subsection
            section = tagInfo.@section
            subGroup = tagInfo.@subgroup
            group = tagInfo.@group
        }
    }
    
    /**
     * Creating the jdbcResponse from the response received, using fixed value for testing
     * If you want, you can assign the response received directly using below instead of current and make sure you replace the step name correctly
     * def jdbcResponse = context.expand('${JdbcStepName#Response}')
     */
    def jdbcResponse = '''<Results>
    <ResultSet fetchSize="128">
        <Row rowNumber="1">
            <ID>1</ID>
            <NAME>TestName1</NAME>
            <DESCRIPTION/>
            <TYPE>Bool</TYPE>
            <ISPRODUCTTAG>true</ISPRODUCTTAG>
            <ISLOCATIONTAG>false</ISLOCATIONTAG>
            <SUBSECTION>Default Sub Section</SUBSECTION>
            <SECTION>Default Section</SECTION>
            <SUBGROUP>Default Sub Group</SUBGROUP>
            <GROUP>Default Group</GROUP>
        </Row>
        <Row rowNumber="2">
            <ID>2</ID>
            <NAME>TestName2</NAME>
            <DESCRIPTION/>
            <TYPE>Bool</TYPE>
            <ISPRODUCTTAG>true</ISPRODUCTTAG>
            <ISLOCATIONTAG>false</ISLOCATIONTAG>
            <SUBSECTION>Default Sub Section</SUBSECTION>
            <SECTION>Default Section</SECTION>
            <SUBGROUP>Default Sub Group</SUBGROUP>
            <GROUP>Default Group</GROUP>
        </Row>
        <!--added 3rd row for testing the failure -->
        <Row rowNumber="3">
            <ID>3</ID>
            <NAME>TestName3</NAME>
            <DESCRIPTION/>
            <TYPE>Bool</TYPE>
            <ISPRODUCTTAG>false</ISPRODUCTTAG>
            <ISLOCATIONTAG>false</ISLOCATIONTAG>
            <SUBSECTION>Default Sub Section3</SUBSECTION>
            <SECTION>Default Section3</SECTION>
            <SUBGROUP>Default Sub Group3</SUBGROUP>
            <GROUP>Default Group3</GROUP>
        </Row>
    </ResultSet>
    </Results>'''
    
    /**
     * Creating the jsonResponse from the response received, using fixed value for testing
     * If you want, you can assign the response received directly using below instead of current and make sure you replace the step name correctly
     * def jsonResponse = context.expand('${JsonStepName#Response}')
    
     */
    def restResponse = '''
    <ArrayOfTagInfo>
       <TagInfo id="1" name="TestName1" type="Bool" isProductTag="true" isLocationTag="false" subsection="Default Sub Section" section="Default Section" subgroup="Default Sub Group" group="Default Group"/>
       <TagInfo id="2" name="TestName2" type="Bool" isProductTag="true" isLocationTag="false" subsection="Default Sub Section" section="Default Section" subgroup="Default Sub Group" group="Default Group"/>
      <!--added 3rd row for testing the failure -->
       <TagInfo id="3" name="TestName3" type="Bool" isProductTag="true" isLocationTag="false" subsection="Default Sub Section" section="Default Section" subgroup="Default Sub Group" group="Default Group"/>
    </ArrayOfTagInfo>'''
    
    //Parsing the jdbc and build the jdbc model object list
    def results = new XmlSlurper().parseText(jdbcResponse)
    def jdbcDataObjects = []
    results.ResultSet.Row.each { row ->
        jdbcDataObjects.add(new Model().buildJdbcData(row))
    }
    
    //Parsing the json and build the json model object list
    def arrayOfTagInfo = new XmlSlurper().parseText(restResponse)
    def jsonDataObjects = []
    arrayOfTagInfo.TagInfo.each { tagInfo ->
        jsonDataObjects.add(new Model().buildJsonData(tagInfo))
    }
    
    //sorting the Data before checking for equality
    jdbcDataObjects.sort()
    jsonDataObjects.sort()
    
    if (jdbcDataObjects.size() != jsonDataObjects.size()) {
        System.err.println("Jdbc resultset size is : ${jdbcDataObjects.size()} and Json result size is : ${jsonDataObjects.size()}")
    }
    assert jdbcDataObjects == jsonDataObjects, "Comparison of Jdbc and Json data is failed"
    

    在上面,第3行不匹配,因此assert将抛出以下错误:

      

    抓到:java.lang.AssertionError:比较失败。表达式:(jdbcDataObjects == jsonDataObjects)。值:jdbcDataObjects = [默认Group3,默认组,默认组],jsonDataObjects = [默认组,默认组,默认组]   java.lang.AssertionError:比较失败。表达式:(jdbcDataObjects == jsonDataObjects)。值:jdbcDataObjects = [默认Group3,默认组,默认组],jsonDataObjects = [默认组,默认组,默认组]       在So31472381.run(So31472381.groovy:104)
      处理以退出代码1完成

    如果你删除第3个(来自两个响应),那么你没有看到任何错误,这表明jdbc和json响应的成功比较。

      

    请注意,groovy script的免费版和专业版都提供SoapUI。所以这个解决方案适用于SoapUI的两个版本。