Groovy+HttpRestfulに基づく超軽量レベルのインタフェーステスト用例構成の設計案及びDEMO実現

6858 ワード

ターゲット


軽量レベルのテスト用例フレームワークを設計し、インタフェーステスト作成者はテスト用例に関する内容(入参および結果検証)を作成するだけで、システムの実現を気にする必要はなく、テスト検証に関係のない内容を書く必要はありません.

構想


テストケース分析


1つの例は、次のセクションで構成されています.
(1)試験用例名;(2)インタフェース名及びURL/Path;(3)インタフェースパラメータ;(4)インタフェースは結果検証を返す.
テストフレームワークは、使用例構成情報を読み出し、指定されたインタフェースおよびパラメータ呼び出しサービスに基づいて、指定された検証関数に基づいてインタフェースの戻り結果を検証し、テスト使用例が成功したかどうかを判断する必要がある.

デザイン


異なるインタフェースを柔軟に呼び出すために、以上の構成に対して、(2)http restful方式を採用する.(3)Mapを採用する.(4)検証構文が必要である.ここではgroovyスクリプトを一時的に直接採用します.

DEMO実装


利用者は何をする必要がありますか?


インタフェーステストケース作成者は、TestCaseクラスを1つ定義するだけでよい.このクラスには、次の情報が含まれています.
(1)テスト対象インタフェースのurl:http://ip:7001およびrestfulパス/xxx
(2)@Case注記付きの方法.中にはMapが戻ってきて、
name:テスト用例名;
param:入参map;
check:関数を検証します.dataは戻る最上位レベルです.
たとえば、検索テストケースクラスSearchTestCases:
package cc.lovesq.study.testcase.qa

import cc.lovesq.study.testcase.Case

class SearchTestCases {

    def url = 'http://ip:7001'
    def path = '/searchApp/order/search'

    @Case
    def get() {
        return [
           'name': 'testSearchOrderNo',
           'param': ['shopId': 55, 'orderNo': 'E20180507200552032000001', 'source':'service-test'],
           'check': { data ->
               data.list.each {
                   order ->
                       order.orderNo == 'E20180507200552032000001'
               }
           }
        ]
    }

}

詳細テストケースクラス
package cc.lovesq.study.testcase.qa

import cc.lovesq.study.testcase.Case

class DetailTestCases {

    def url = 'http://ip:7001'
    def path = '/detailApp/orderInfo/byOrderNo'

    @Case
    def get() {
        return [
           'name': 'testSingleOrderDetail',
           'param': ['shopId': 55, 'orderNo': 'E20180507200552032000001', 'source':'service-test', 'bizGroup': 'trade'],
           'check': { data ->
               data.mainOrderInfo.orderNo == 'E20180507200552032000001'
           }
        ]
    }

}

フレームワークの基本的な実装


指定したTestCaseクラスを通じて、その使用例構成情報を読み出し、その中の使用例構成を識別し、Httpでインタフェースを呼び出し、指定した検査関数をコールバックして結果を検査する.
package cc.lovesq.study.testcase

import groovyx.net.http.ContentType
import groovyx.net.http.HTTPBuilder
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import static groovyx.net.http.Method.POST

class CaseExecutor {

    static Logger log = LoggerFactory.getLogger(CaseExecutor.class)

    def invokeAllCases(testCase) {
        Object tc = testCase
        tc.getClass().getDeclaredMethods().findAll {

            //  :   @Case
            it.getAnnotation(Case.class) != null

        }.each {
            it ->
                def caseInfo = it.invoke(tc, null)
                def result = exec(caseInfo['name'], tc.url, tc.path, caseInfo['param'], caseInfo['check'])
                println("case=${caseInfo['name']}, result=${result}")
        }
    }

    def exec(name, url, path, param, check) {

        def http = new HTTPBuilder(url)

        def result

        http.request(POST) {
            uri.path = path
            requestContentType = ContentType.JSON
            body = param

            response.success = { resp, json ->
                def data = json.data.data
                try {
                    log.info("Enter Test Case : {}", name)
                    check(data)
                    result = "success"
                } catch (Throwable e) {
                    result = "failed"
                } finally {
                    log.info("Exit Test Case : {}", name)
                }
            }
            response.failure = { resp ->
                println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}"
                def errorInfo = """
                    Call error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}
                    Name: ${name}
                    Url: ${url}
                    Path: ${path}
                    Param: ${param}
                """
                log.warn(errorInfo)
                result = "failed"
            }
        }
        result
    }
}

クライアント実行テストケースセット:
package cc.lovesq.study.testcase

import cc.lovesq.study.testcase.qa.DetailTestCases
import cc.lovesq.study.testcase.qa.SearchTestCases

class ClientTest {

    def static main(args) {

        CaseExecutor caseExecutor = new CaseExecutor()

        caseExecutor.invokeAllCases(new SearchTestCases())
        caseExecutor.invokeAllCases(new DetailTestCases())

    }
}

コードの説明

  • は、HTTP要求を送信するためにHttpBuilderクラスを使用する.POM構成の追加が必要:
  • 
          org.codehaus.groovy.modules.http-builder
          http-builder
          0.6
    
  • は、注釈@Caseを使用して試験例を表す.注記は、オブジェクトのクラスを識別するために使用できます.
  • はGroovy閉パケットを使用して検証ロジックを伝達する.閉パケットは、変化する論理を伝達するために使用することができる.

  • オートローディング・インスタンス・セット


    実際のアプリケーションでは、XXXTestCasesオブジェクトを直接newするのではなく、これらのオブジェクトをComponentとマークした後、アプリケーションの起動時にこれらのTestCasesをロードし、マッピングを確立することがよくあります.CaseExecutorをいくつか拡張すればいいです.次のコードを示します.
    @Component("caseExecutor")
    class CaseExecutor implements ApplicationContextAware {
    
        static Logger log = LoggerFactory.getLogger(CaseExecutor.class)
    
        ApplicationContext context
    
        def casePathMap = [:]
    
        @PostConstruct
        def init() {
            Map components = context.getBeansWithAnnotation(Component.class)
            log.info("{}", components)
            components.each {
                name, comp ->
                    try {
                        def property = comp.metaClass.getProperty(comp, 'path')
                        if ( property) {
                            casePathMap[property] = comp
                        }
                    } catch (e) {
                        log.warn("not having restPath, omit")
                    }
    
            }
        }
    
       // other codes
    
        @Override
        void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.context = applicationContext
        }
    }

    小結


    本論文では,Groovy+HttpRestfulに基づく超軽量レベルのインタフェース試験用例構成の設計案とDEMO実装について説明した.この方法に基づいて、冗長なテストコードを追加的に記述する必要がなく、指定されたサービスインタフェースのテスト用例セットを構成的に迅速に増加させることができる.
    転載先:https://www.cnblogs.com/lovesqcc/p/9806293.html