Jmeter-BeanShell斷言的運用一(JSON響應數據與數據庫比對)


前言

  最近在學習BeanShell斷言,發現有點強大哈,只要會寫代碼,就沒有什么是斷言不了的,哈哈哈,不過我現在只會寫點蹩腳的代碼,下面將介紹下如何將返回的JSON數據與數據庫數據做對比。

注:本次涉及到的知識點有 1)BeanShell PostProcessor拼接字符串;2)BeanShell 斷言的基本使用;

背景

  jmeter斷言接口返回的count與數據庫查詢出來的是否一致,接口返回的JSON響應數據如下:

  (count說明:比如12/17,即12是代表商品數 [先用X代替],17是代表收藏夾的數量 [用Y代替])XY只是為了方便區分,后面方便偷懶,哈哈。

{
    "code":"0",
    "msg":"OK",
    "info":{
        "categoryList":[
            {
                "id":45,
                "categoryName":"ca文件夾",
                "imageUrlList":[
                    "https://img/29/15302571783635805807.jpg"
                ],
                "count":2,
                "tip":null
            }
        ],
        "count":"12/17"
    }
}

思路

  第一步:用sql分別查出商品數和收藏夾數,然后拼接成“12/17”的形式;

  第二步:提取出響應數據的count值;(這一步其實有很多種實現方法,比如用jsonpath也可以提取,但本次用的是BeanShell取值哈)

  第三步:將提取出的count與數據庫查詢說來的拼接值做對比,判斷是否一致。

一、BeanShell知識點摘要(*必看

  如果之前沒有接觸過BeanShell的話,這節一點要仔細看哈,雖然只是簡單提及幾個知識點。

1、什么是Bean Shell

  • BeanShell是一種完全符合Java語法規范的腳本語言,並且又擁有自己的一些語法和方法;
  • BeanShell是一種松散類型的腳本語言(這點和JS類似);
  • BeanShell是用Java寫成的,一個小型的、免費的、可以下載的、嵌入式的Java源代碼解釋器,具有對象腳本語言特性,非常精簡的解釋器jar文件大小為175k。
  • BeanShell執行標准Java語句和表達式,另外包括一些腳本命令和語法。
  • BeanShell斷言中可以通過ResponseCode、ResponseHeaders及pre.getResponseDataAsString()來分別獲得String格式的響應狀態碼、響應頭、響應體數據,結合if判斷通過變量Failure=false或Failure=true來設置斷言是否通過,當設置Failure=true時,還可以設置FailureMessage來設置失敗原因

2、Bean Shell常用內置變量

    JMeter在它的BeanShell中內置了變量,用戶可以通過這些變量與JMeter進行交互,其中主要的變量及其使用方法如下:

  • log:寫入信息到jmeber.log文件,使用方法:log.info(“This is log info!”);

  • ctx:該變量引用了當前線程的上下文,使用方法可參考:org.apache.jmeter.threads.JMeterContext

  • vars - (JMeterVariables):操作jmeter變量,這個變量實際引用了JMeter線程中的局部變量容器(本質上是Map),它是測試用例與BeanShell交互的橋梁,常用方法:

    a) vars.get(String key):從jmeter中獲得變量值

    b) vars.put(String key,String value):數據存到jmeter變量中

    更多方法可參考:org.apache.jmeter.threads.JMeterVariables

  • props - (JMeterProperties - class java.util.Properties):操作jmeter屬性,該變量引用了JMeter的配置信息,可以獲取Jmeter的屬性,它的使用方法與vars類似,但是只能put進去String類型的值,而不能是一個對象。對應於java.util.Properties。 

    a) props.get("START.HMS");  注:START.HMS為屬性名,在文件jmeter.properties中定義 

    b) props.put("PROP1","1234"); 

  • prev - (SampleResult):獲取前面的sample返回的信息,常用方法:

    a) getResponseDataAsString():獲取響應信息

    b) getResponseCode() :獲取響應code

    更多方法可參考:org.apache.jmeter.samplers.SampleResult

  • sampler - (Sampler):gives access to the current sampler

3、Bean Shell判斷返回的JSON

  首先要下載JSON依賴包(org.json.jar),放到\apache-jmeter-5.0\lib\ext中,然后重啟jmeter即可在beanshell中import json包了。具體要怎么提取到JSON中的某個值,在博文最后會貼代碼,請拉到最后查看,后續也會根據不同的JSON結構專門寫一篇如何提取JSON結構字段值的文章。

4、JSONObject對象除了getString()方法外,還支持

  • getBoolean("字段名") :獲取布爾類型字段值
  • getInt("字段名"):獲取整型字段值
  • getLong("字段名"):獲取長整型字段值
  • getDouble("字段名"):獲取雙精型字段值
  • getJSONObject("字段名"):獲取嵌套Object類型字段值,JSONObject類型
  • getJSONArray("字段名"):獲取嵌套Array類型,JSONArray類型

5、簡單斷言舉例

狀態碼斷言

//狀態碼斷言
log.info("狀態碼:" + ResponseCode);
if(ResponseCode.equals("200")){ 
    Failure=false;
}
else{
    Failure=true;
    FailureMessage="響應狀態碼非200";  //指定失敗原因
}

注:字符串只能使用雙引號,字符串相等要使用"".equals("")

響應體包含特定字符

//獲取響應數據
String response = prev.getResponseDataAsString();
log.info("響應體:" + response);
//響應數據包含
if(response.contains("登錄成功")){
    Failure=false;
}
else{
    Failure=true;
    FailureMessage="響應數據不包含登錄成功";
}

二、實例操作第一步:sql查詢

  jmeter連接數據庫在之前就已經講過了,這里就不再贅述了哈,直接進入主題了。這次的查詢比較特別一點,為什么呢?因為查詢用到的表在不同的數據庫中,不是同一個庫了,為了方便理解,還是大概說一下吧。

category表在A庫,collect表在B庫,在查collect表里的商品數時,是需要用到category表查詢出來的id的,因為查詢出來的id可能不止一個,所以就會涉及到要將id拼接成一個list的字符串,例如:ids = 1606973,1606974,1606975

最后將其作為參數,再放到collect表里查詢。說的可能比較抽象,哈哈哈,下面直接上圖了。

1、查詢category表的文件夾總數,即count中的X

  添加JDBC Request,具體寫法如下:

2、查詢category表的文件夾的id(用在另一個庫的數據表的)

  添加JDBC Request,具體寫法如下:

3、將category表查詢出的文件夾的id拼接起來

  添加BeanShell PostProcessor,編寫簡單的Java代碼,循環所有的id,拼裝成list字符串,並保存到參數中,供后續sql查詢時調用,Script寫法如下:

//先取得id的數量,即查詢出來一共有多少個id,這里可以直接引用A_#,可以看debug sampler
log.info("ids的數量為:"+vars.get("A_#"));
int id = Integer.valueOf("${A_#}");

//定義變量ids,用來存放拼接后的字符串
String ids = "";

//用id數量去for循環,循環查詢出每個id,並拼接成字符串
for(i=1; i<=id; i++){
    String Id = vars.get("A_"+i);
    log.info("Id為:" + vars.get("A_" + i));
    ids += Id + ",";
    }

//去掉字符串最后一個多余的逗號
ids = ids.substring(0, ids.length() - 1);

log.info("ids為:" + ids);

//將id列表保存為參數
vars.put("ids",ids);

4、查詢collect表的商品總數,即count中的Y

  添加JDBC Request,具體寫法如下:

三、實例操作第二、三步:提取JSON字段和斷言

  添加背景里說到的接口的http請求,在http請求里添加BeanShell斷言,Script寫法如下:

//導入json的包
import org.json.*;

//獲取響應結果,並轉換為json
String response = prev.getResponseDataAsString();
JSONObject responseJson = new JSONObject(response);
log.info("輸出轉換為JSON對象的響應數據:" + responseJson);

/*獲取categoryList數組的數據:這個與本次斷言無關
JSONArray categoryList = responseJson.getJSONObject("info").getJSONArray("categoryList");
log.info("categoryList:" + categoryList);
String message = responseJson.getString("msg");
log.info("響應message字段:" + message);
*/

//獲取count的值
String count = responseJson.getJSONObject("info").getString("count");
log.info("請求響應結果返回的count的值為" + count);

//將數據庫查詢出來的文件夾總數和商品總數拼接起來,比如12/19
sqlcount=${B_1}+"/"+${C_1};
log.info("第一種方法直接引用變量去拼接的值為:"+sqlcount);

String sqlcountB = vars.get("B_1");
String sqlcountC = vars.get("C_1");
sqlcount2= sqlcountB +"/"+sqlcountC;
log.info("第二種方法用vars.get到值再拼接的值為:"+sqlcount2);


//斷言返回的count與數據庫的count是否一致
//if(count.equals("12/17")){
if(count.equals("sqlcount")){
    Failure=false;
    log.info("數據一致"+"-----count的值為:"+count+"------sqlcount的值為:"+sqlcount);
}
else{
    Failure=true;
    FailureMessage="不相等呀,請檢查!!!"+"count的值為:"+count+"------sqlcount的值為:"+sqlcount;
    log.info(FailureMessage);
}

四、線程組框架展示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM