日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

接口入参形式_花椒测试平台 接口篇

發布時間:2023/12/15 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 接口入参形式_花椒测试平台 接口篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

先來說說花椒測試平臺的由來:

  • 目的1,降低接口測試對測試人員代碼能力的要求。測試人員只需要知道接口的url,請求參數,以什么樣的格式傳個服務端,接口的響應數據里需要驗證哪個字段的值即可進行測試,而不需要知道怎么建一個工程,怎么建一個測試類,測試方法,testng是怎么使用的,結果怎么解析,怎么取到想要的字段去做判斷。

  • 目的2,可視化的case管理,執行,結果管理。打開一個瀏覽器,根據接口文檔新建一個測試case,執行檢查接口返回,保存case,建不同入參的該接口的case,組成case集,批量運行,查看運行結果,相比于工程執行批量case,testng的html結果,平臺的集中展示更清晰。

  • 既然接口的測試已經有case的信息了,對接口進行壓測的請求其實也類似一個case,只不過是有很多人在同時執行這個case,所以有了壓力測試和接口測試平臺的整合。在平臺建壓測任務的時候選定一個測試用例為載體,多并發的執行case,統計壓測數據,實時展示。以往接口測試和壓力測試都是分別寫一個方法,里面有很多重復的部分。

  • 接下來我們會想,像接口測試是由數據驅動的,那么UI自動化是否可以理解為一種另類的驅動呢?UI操作的公共方法如點擊,輸入,檢查元素的值,其實和接口入參和結果檢查很像,基于cucumber我們將UI自動化集成進了測試平臺,測試人員只需要關心我點擊的是哪個頁面的那個button或輸入的內容,期望那個元素是什么展示即可,降低了測試人員的代碼門檻,app頁面發生變化時,case維護成本較原來的通篇代碼修改有所降低。

花椒測試平臺整個框架

說了這么多,先來看看花椒測試平臺的整個框架:

該框架主要由三大部分組成,今天主要介紹接口部分的一體化(接口測試+壓力測試):

Web平臺

Web平臺是花椒測試平臺的核心部分,主要是給測試開發人員提供可視化的界面操作,并封裝為參數信息,調用后端的接口服務處理,展示處理結果給用戶。后端采用Springboot + Mybatis框架,前端頁面用jsp開發,后續UI自動化和部分工具的前端頁面也有用vue框架開發,權限管理用的shiro,做好詳細的權限管理,因為如果操作線上case,很有可能會對線上真實用戶造成影響,所以線上case的權限只對部分人員開放,另外比如壓測的功能,也需要做好權限管理,同時后端會記錄每個用戶的操作行為,便于追查。測試平臺模塊主要包含以下幾個:

Case管理

Case管理部分,主要是管理包括接口case,場景case,bvtcase等的增加,修改,和在線執行

接口Case
  • case增加,刪除,更新,另存為新用例,查找

    case結構信息如下:

cases` (
運行環境:測試環境,預發布,線上

模塊:根據業務劃分的模塊

優先級:重要級別

Guid:特殊校驗方式

參數格式:content-type和業務的結合,特殊的業務有特殊定義

用例名稱,用例說明

url:接口url

Token,請求頭信息:請求頭信息里的,Token標識用戶

用例變量:抽取出來的變量,方便更改

請求參數:json結構體key-value的方式存儲請求信息,后端請求的時候按參數個數組裝

期望返回驗證:對結果的校驗,目前有等于,包含,自定義方法上線文驗證等

)

??以用戶更新測試用例為例來看一下整個交互流程:

??用戶瀏覽器一個case,網頁請求后端服務器,Shiro判斷登陸狀態跳轉頁面到第三方登陸,輸入用戶名密碼后調第三方登陸服務,用戶錯誤返回登陸失敗,用戶正確向數據庫查詢用戶角色和權限,返回展示case頁面及有權限的menu,用戶修改case信息,編輯后點擊保存,網頁向服務器請求接口,服務器判斷用戶是否有訪問權限,有權限則保存case更新到數據庫,返回頁面展示保存成功,沒有權限則返回頁面展示“保存失敗,沒有權限操作”

  • case測試執行

    前端獲取頁面的case信息,URL,請求method,加解方式,參數,期望驗證,以form的形式請求后端js_case_execute接口執行測試用例,服務器內部解析請求內容,調用case處理中心模塊CaseRunner組裝請求,向測試服務器發起請求,根據預設的斷言,判斷case的運行接結果,并將結果和服務器的返回組裝成json格式返回給頁面展示,頁面的json展示用了開源的JSONFormatter.js (https://webscripts.softpedia.com/script/Development-Scripts-js/HTML-Tools/JSONFormatter-js-76391.html),能夠根據各個層級展開和疊起,方便測試人員查看數據返回。js_case_excute實行如下:

????@ResponseBody
????@RequestMapping(value?=?"/js_case_execute",?method?=?RequestMethod.POST)
????public?Response?js_case_execute(Case?hjcase,?HttpServletRequest?request)?{
????????RequestUtil.preResetField(request,?hjcase);
????????try?{
????????????List?resultList?=?new?ArrayList();
????????????CaseResult?hjresult?=?new?CaseResult(hjcase.getId(),?hjcase.getCasename(),?-1,?"");
????????????executeCase(hjcase,?hjresult);
????????????resultList.add(hjresult);//?把該case加入我的常用case列表,方便使用
????????????RedisService.addToMyFavCase(SecurityUtils.getSubject().getSession().getAttribute(Const.SESSION_USER),?hjcase.getId()?+?"_"?+?hjcase.getCasename());return?new?Response(resultList);
????????}?catch?(ParamFormatException?e)?{//e.printStackTrace();return?new?Response(1,?e.getMessage());
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();return?new?Response(1,?"Exception---"?+?e.getMessage());
????????}
????}
  • case批量運行

由于測試過程中經常會有制造批量數據,小并發運行的需求,并發支持對請求變量值設置數組運行,多線程隨機或順序取數組里的用戶執行case,統計case耗時和平均響應時間,頁面設置如下:

批量實現:

??@ResponseBody
??@RequestMapping(value?=?"case/batchExecCase")
??public?Response?batchExecCase(Case?hjcasesrc,?HttpServletRequest?request)?{
??????RequestUtil.preResetField(request,?hjcasesrc);
??????if?(hjcasesrc.getCasetype()?==?2)?{
??????????//?suite?case?只支持以數據庫的為準
??????????try?{
??????????????List?subCases?=?caseService.findByIds(hjcasesrc.getCaseids());
??????????????hjcasesrc.setSubCases(subCases);
??????????}?catch?(Exception?e)?{
??????????????e.printStackTrace();
??????????}
??????}//?把需要批量運行是替換的參數解析,需多線程訪問
??????Response?response?=?new?Response();?//?response?傳遞為了返回運行時數據,?所有線程都共享該response,且可以修改其值,?不使用靜態對象是因為多個并發請求會相互影響try?{
??????????List?keyinfos?=?hjcasesrc.getBatchKeyInfos();
??????????httpUtils?utils?=?new?httpUtils();//?提前取用戶登陸信息,獲取出來,?都放入sampleList中,并且設置sampleType=2for?(BatchKeyInfo?keyinfo?:?keyinfos)?{if?(!keyinfo.isToken())?{continue;
??????????????}
??????????????...//省略獲取用戶信息break;
??????????}
??????????response.put(Response.TOTAL,?totalBatch);
??????????List?threadPool?=?new?ArrayList();for?(int?i?=?0;?i???????????????httpUtils?httputils?=?new?httpUtils();
??????????????CaseRunner?runner?=?new?CaseRunner(hjcasesrc,?keyinfos,?httputils,?response);
??????????????runner.setRunTime(totalBatch);
??????????????Thread?runnerThread?=?new?Thread(runner);
??????????????threadPool.add(runnerThread);
??????????}???????long?starttime?=?System.currentTimeMillis();for?(Thread?worktask?:?threadPool)?{
??????????????worktask.start();
??????????????worktask.join();
??????????}long?endtime?=?System.currentTimeMillis();float?avgTPS?=?(float)?totalBatch?/?((endtime?-?starttime)?/?1000.0f);
??????????response.put("Comsume",?endtime?-?starttime);
??????????response.put("avgTPS",?String.valueOf(avgTPS));
??????}?catch?(Exception?e)?{
??????????e.printStackTrace();
??????}return?new?Response(response.getResultJSON());
??}
場景case

場景case來源于用戶的一系列有聯系的操作行為,比如用戶A想要和主播B連麥,A先發起連麥,B主播同意,A用戶同意,然后用戶A和主播B連麥成功,這里面就有3個接口,一個是發起的apply接口,同意的accept接口,和開始連接的connect接口,所以組成這個場景的子case有三個,case1用戶A發起apply,成功后返回申請的id傳遞給case2/case3, case2主播accept連麥, 請求的用戶信息是主播B, case3用戶B開始connect連麥。執行的整個過程是,先抽取變量,執行case1,處理斷言信息,賦值返回的申請id,然后執行case2,case2的傳參申請id用case1返回的id同意申請,case3用case1的申請id開始連麥,整個過程的順序必須是case1->case2->case3。場景 case存儲時,抽離出每個case的用戶信息,輸入,期望判斷信息,如“0”:values,組成一個大的jsonobject,case運行時,解析結構體,順序執行,case的主數據庫結果體信息如下:

BVTCase集

BVTCase為各模塊接口case集管理中心,case集可以共享請求服務器地址,用戶等信息,case集內可以定義case的執行優先級,執行整個case集,查看執行結果,對外給發布系統提供查詢,執行測試集的接口并返回結果給發布系統判斷是否允許發布。另外也增加了crontab任務定期執行。

新建測試Suite,編輯測試Suite,編輯測試case順序,執行測試Suite,批量執行測試Suite
對外代碼發布系統獲取測試Suite列表,指定測試Suite信息,調用測試Suite執行
  • inter/getSuiteLists獲取測試集列表,可指定模塊,如passport,live等

  • inter/getSuiteInfo獲取指定id的suite信息,全部變量及各子case信息

  • inter/execSuiteList執行測試集,并返回測試集執行結果,成功失敗,測試集的詳細結果的訪問方式

  • 結果集,為測試suite執行的結果列表頁面,記錄執行結果,耗時已經執行人的信息:

    結果集名稱,總條數,成功條數,失敗條數,狀態(成功,失敗),執行人

    工具管理

    平臺工具管理中心,主要包含兩種類型的工具,一種是jar包等上傳可執行文件的工具,一種是在線使用工具:

    • 可執行文件工具
      平臺支持添加腳本,上傳jar包,指定傳入的參數等,保存腳本信息,支持編輯更新,測試執行

    • 在線使用的工具

      該類工具如網頁版的redis查詢工具,byte string轉換,數據清理等各種小工具,可以根據業務測試中的各種需求開發各種能提升效率的小工具,如下面這個byte string轉換小工具,功能很簡單,但解決了手工測試無法看到內容的困擾,提升了定位問題的效率

    壓力測試管理

    壓測場景

    支持新建,更新壓測場景,壓測場景綁定已經建好的接口測試用例,修改用例變量值如用戶id來實現多用戶壓測場景,壓測場景包含的信息如下:

    壓測場景{

    模塊:選擇壓測場景屬于的業務模塊

    用例id:選擇壓測的case

    壓測場景:壓測的場景的名字

    場景說明:該壓測的信息說明,如多少個用戶,多少并發

    壓測服務部署機器:部署壓測服務的機器IP

    啟動線程個數:并發線程個數

    運行次數:執行多少次case

    發送間隔:每個線程每個請求處理完后的休息間隔(可為0)

    用例變量:從選擇的用例id里帶過來的用例變量,便于壓測過程中修改方便

    壓測參數:對用例變量進行取集合值,或從指定數值開始的多少個數,常用于多用戶的場景壓測

    }

    壓測執行

    點擊啟動壓測任務

    壓測結果

    點擊結束任務時,當次壓測的數據匯總回寫到結果數據表,統計請求TPS(reqTPS),響應時間(respTime),響應TPS(respTPS)的最大最小值和平均值,以及總請求個數,以及失敗的請求個數。

    壓測服務

    壓測服務是執行壓力測試的中心服務,可以部署在任意可執行壓測任務的服務器(有java環境即可),主要邏輯是監聽從web,或者PC壓測Client傳過來的壓測指令,根據執行獲取壓測信息,起線程進行壓力測試,每秒統計一次壓測數據,并將數據同步到數據庫,供web平臺展示查看實時壓測結果并進行壓測調整。

    主要包含以下幾個主要模塊:

    監聽服務

    監聽務是指啟動一個socket server來監聽指定端口,收到指令,為了保證安全性,先判斷指令發送IP是否在白名單內,如不在,拒絕服務;解析命令內容,命令內容以TasK*開頭,則代表從測試平臺來的命令,執行相應操作,如啟動任務,執行壓測任務(CaseRunner分支),更新任務信息,結果任務等;如果命令內容直接以Start,任務名稱等開頭,則走自定義壓測執行壓測任務(WorkTask分支),自定義部分適合復雜場景和統計需求的壓測。

    ...//以收到啟動命令為例
    if(cmd.equals("TaskStart")){?//?啟動線程,初始化變量???????????????????????????????????
    ????int?content?=?Integer.parseInt(params[1]);?????????????????????????????????????????????//?非結束狀態,說明?可能有些初始化或銷毀操作是需要進行的,?必須&&?非下面兩種狀態時處理?????????????
    ????if(CommonTaskData.getSTATE()?==?CommonTaskData.RUNNING?||?CommonTaskData.getSTATE()?==?CommonTaskData.PAUSE)???//?從?start?之后?還是start--????????????????????????
    ????{
    ????????if(CommonTaskData.getId()?==?content)?{
    ????????????//?如果還是同一個task,?則只需重新更新一下task即可??
    ????????????CaseHelper?casehelper?=?CaseHelper.getInstance();?????????????????????????????????????????StressTaskHistory?taskhistory?=?casehelper.getTaskHistory(content);???????????????????????CommonTaskData.setTask(taskhistory.parseStressTask());???????????????????????????????????System.out.println("從暫停狀態中恢復~~");???????????????????????????????????????????????????for(CaseRunner?runner?:?caseRunners){??????????????????????????????????????????????????????????????runner.setState(CommonTaskData.RUNNING);???????????????????????????
    ????????????}?
    ????????????CommonTaskData.setSTATE(CommonTaskData.RUNNING);???????????????????????????????????????????????????????????????????continue;??????????????????????????????
    ????????}?else{?
    ????????????System.out.println("不同TaskId?Start?----先清理之前線程");???????????????????????????????????for(CaseRunner?runner?:?caseRunners){
    ????????????????runner.setState(CommonTaskData.STOP);?????????????????????????????????
    ????????????}
    ????????????for(Thread?worktask?:?threadPool){//?等待3s的銷毀時間?銷毀原來的線程池
    ????????????????try?{
    ????????????????????worktask.join();????????????????????????????????????
    ????????????????}?catch?(InterruptedException?e)?{
    ????????????????????e.printStackTrace();????????????????????????????????????
    ????????????????}?????????????????????????????????????????????????????????????????
    ????????????}???????????????????????????????????????????????????????????????
    ????????}????????????????????????
    ????}
    ????Statistics.startSampling();?//啟動壓測統計服務

    ????...//準備壓測執行的數據,讀取case和task信息???

    ????//設置運行狀態,啟動線程
    ????CommonTaskData.setSTATE(CommonTaskData.RUNNING);?????????????????????????
    ????for(int?i?=0;?i?????????CaseRunner?runner?=?new?CaseRunner();???????????????????????????
    ????????runner.setState(CommonTaskData.RUNNING);???????????????????????????
    ????????Thread?worktask?=?new?Thread(runner);???????????????????????????
    ????????threadPool.add(worktask);???????????????????????????
    ????????caseRunners.add(runner);???????????????????????????
    ????????worktask.start();????????????????????????}?????????????????????????????????????????????}
    ????...

    壓測任務處理

    根據測試平臺或PC client發過來壓測任務,CaseRunner執行相應的case,并將請求的結果,如成功與否,請求的響應時間等發送給Statistic統計服務進行打點統計,目前CaseRunner執行方式的壓測適用與web的http同步請求,而自定義壓測方式的worktask則既可以定義同步的等待響應后發送下一個請求的方式;也可定義直接往服務器扔請求,異步接收線程處理響應結果及給Statistic統計服務發送打點數據。下面一CaseRunner同步執行的方式為例:

    @Override
    public?void?run()?{?????????
    while(true)
    {????????????
    ????...停止,暫停等狀態,中斷執行

    ?????casedata.copyFrom(CommonTaskData.getBasecase());?
    ?????casedata.appendGlobalVar(varMap);
    ?????CaseResult??caseresult?=?new?CaseResult();

    ?????String?actionName?=?"Task"?+?CommonTaskData.getTask().getId();
    ?????try?{
    ?????????Statistics.OnRequestSend(actionName);
    ?????????long?pre?=?System.currentTimeMillis();
    ?????????utils.runCase(casedata,?caseresult);
    ?????????long?after?=?System.currentTimeMillis();
    ?????????//根據case執行成功失敗,打點
    ?????????if?(caseresult.getStatus()?==?1)?{
    ?????????????Statistics.OnResponseRecv(actionName);
    ?????????????Statistics.onResponseTimeRecv(actionName,?after?-?pre);
    ?????????}
    ?????????else{?????????????????????
    ?????????????Statistics.onFailedResp(actionName);
    ?????????????try{
    ?????????????????if(casedata.getCasetype()?==?1){
    ?????????????????????...//根據case里設置的斷言,統計特殊需求的失敗,總個數和失敗請求的響應時間
    ?????????????????}
    ?????????????}
    ?????????????catch(Exception?e)
    ?????????????{????
    ????????????????System.out.println("CaseRunner(114)?-?Exception-"?+?e.getMessage());?
    ?????????????}
    ?????????????Logger.SysOutput("Fail:"?+?caseresult.getResult().toString());
    ?????????}????

    ?????}?catch?(Exception?e)?{
    ?????????e.printStackTrace();
    ?????????Logger.SysOutput("CaseRunner(123)?-?Exception:"?+?e.getMessage());
    ?????}

    ?????//?測試場景如果設置的發送間隔,則sleep
    ?????if(CommonTaskData.getSleeptime()?>?0){
    ????????????if(CommonTaskData.getSleepRan()?==?1){
    ?????????????????Tools.sleep(RamNum.GetRamInt(CommonTaskData.getSleeptime()));????????????
    ????????????}else{
    ?????????????????Tools.sleep(CommonTaskData.getSleeptime());
    ????????????}????????????????
    ?????}
    }
    }

    Statistic壓測結果統計

    統計每秒的請求數,響應數,響應時間,失敗數等,如果是平臺的壓測請求,將壓測數據根據需求記入數據庫,供web平臺展示用,具體實現如下

    @Overridepublic?void?run()?{
    ????long?lastSampleTime;

    ????while(!stopSample){
    ????lastSampleTime?=?System.currentTimeMillis();

    ????try{
    ????????Thread.sleep(samplePeriod);
    ????????Object[]?actionNameSet?=?actions.keySet().toArray();
    ????????for(Object?key?:?actionNameSet){
    ????????????Action?action?=?actions.get(key.toString());

    ????????????if?(!key.toString().startsWith("Task"))?{
    ????????????????action.Sample(lastSampleTime);//統計請求信息,并打印
    ????????????????action.SampleResponseTime(lastSampleTime);//統計響應時間信息,并打印
    ????????????}?else?{
    ????????????????action.SampleRedis(lastSampleTime);//統計請求信息,響應,打印并存庫
    ????????????}
    ????????}
    ????}catch(InterruptedException?e){
    ????????System.out.println("Sample?thread?stop?for?interrupted?exception.");
    ????????break;
    ????}
    }
    }

    后續計劃

    目前測試平臺只集成了自動化測試的基本功能,在持續集成上的應用還需要豐富起來,另外作為一個質量管理平臺,對提測->測試 -> 測試bug記錄->測試結果->上線的整個過程并沒有完整的整合起來,也是我們后續需要完善的地方。

    - To Be Continued?-


    我建立的知識星球,提升技術認知,助力技術成長!歡迎掃碼加入:

    總結

    以上是生活随笔為你收集整理的接口入参形式_花椒测试平台 接口篇的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。