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語句和表示式,另外包括一些指令碼命令和語法。
2、Bean Shell常用內建變數
JMeter在它的BeanShell中內建了變數,使用者可以通過這些變數與JMeter進行互動,其中主要的變數及其使用方法如下:
-
log:寫入資訊到jmeber.log檔案,使用方法:log.info(“This is log info!”);
-
ctx:該變數引用了當前執行緒的上下文,使用方法可參考:
-
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結構欄位值的文章。
二、例項操作第一步:sql查詢
jmeter連線資料庫在之前就已經講過了,這裡就不再贅述了哈,直接進入主題了。這次的查詢比較特別一點,為什麼呢?因為查詢用到的表在不同的資料庫中,不是同一個庫了,為了方便理解,還是大概說一下吧。
category表在A庫,collect表在B庫,在查collect表裡的商品數時,是需要用到category表查詢出來的id的,因為查詢出來的id可能不止一個,所以就會涉及到要將id拼接起來,再放到collect表裡查詢。說的可能比較抽象,哈哈哈,下面直接上圖了。
1、查詢category表的資料夾總數,即count中的X
新增JDBC Request,具體寫法如下:
2、查詢category表的資料夾的id(用在另一個庫的資料表的)
新增JDBC Request,具體寫法如下:
3、將category表查詢出的資料夾的id拼接起來
新增BeanShell PostProcessor,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); }