效能測試乾貨分享:JMeter如何使用Bean Shell進行引數化?
在效能測試過程中,為了能夠真實模擬使用者請求,往往要將請求的報文進行引數化處理。JMeter配置元件與前置處理器都可以進行引數化,但都存在侷限性。為了幫助使用者更好地進行引數化,JMeter提供了BeanShell取樣器。
BeanShell取樣器支援BeanShell指令碼語言,這是一種完全符合Java語法規範的指令碼語言。下面就以一個樣例來說明,如何使用BeanShell來進行引數化。加我VX:atstudy-js 回覆“測試”,進入軟體測試學習交流裙~~用例示例如下:
1.需求場景
有一個TCP服務,接收並處理地理位置上報的報文。報文由以下幾部分組成:訊息頭+訊息體+校驗碼。其中,除了訊息體之外,其他部分可以是固定的,訊息體包含地理位置的經緯度、速度訊息和傳送時間。經緯度是長度為8位的16進位制字串,速度訊息也是8位的16進位制字串,可以固化,傳送時間是時間戳。要求上報的位置訊息頻率是1秒,每次上報的位置需不同。
TCP服務接收到位置報文之後,進行業務處理,然後返回一個16進位制的報文。
2.測試指令碼準備
對於此測試需求,光使用JMeter內建的函式,是不能滿足的,因此考慮使用Bean Shell處理,透過編寫Java方法的方式進行引數化設定。
開啟JMeter,按以下步驟進行操作。
(1)新增執行緒組
在測試計劃上右鍵點選->新增->執行緒(使用者)->執行緒組:
執行緒組設定如下:
執行緒組名稱設為:BeanShell示例。這裡設定100個執行緒,迴圈1次,也就是要傳送100個請求,每個請求的報文都不相同。
(2)新增Bean Shell取樣器
線上程組上右鍵->新增->取樣器->Bean Shell取樣器:
新增成功後如下圖所示:
(3)編寫Bean Shell指令碼
用Java編寫以下指令碼:
package com.example.rabbitmq.rabbitmq;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Baowen {
// 出發城市的經度
private static double Depart_City_longitude = 110.330685;
// 出發城市的緯度
private static double Depart_City_latitude = 20.035221;
// 抵達城市的經度
private static double Arrival_City_longitude = 110.720005;
// 抵達城市的緯度
private static double Arrival_City_latitude = 19.610221;
// 兩個城市之間單程的位置點數
private static int count = 5000;
private static String dateFormate = "yyMMddHHmmss";
private static String baseTime = "200609153143";
// 報文字首
private static String beginMsg = "02004022018986042206198026706200010000000000000003";
private static String midMsg = "000B00020111";
// 報文字尾
private static String endMsg = "010400000000EE7E";
// 經度上移動的步頻
private static Double getLongitudeStep() {
return (Depart_City_longitude - Arrival_City_longitude) /count;
}
// 緯度上移動的步頻
private static Double getlatitudeStep() {
return (Depart_City_latitude - Arrival_City_latitude) /count;
}
// 把整數轉換為長度8位的16進位制字串
private static String integer2HexString(Integer number) {
String result = Integer.toHexString(number);
int len = result.length();
StringBuilder sb = new StringBuilder("");
// 不足8位時,前面補0
if(len < 8) {
for(int i = len; i < 8; i++) {
sb = sb.append("0");
}
sb.append(result);
}
return sb.toString();
}
public static String getLocationMsg(int num) {
double longitude, latitude;
// 如果位置點已經到達目的城市,則需返回,上傳返程的位置點加我VX:atstudy-js 回覆“測試”,進入軟體測試學習交流裙~~用例示例如下:
if((Depart_City_longitude - num*getLongitudeStep()) >= Arrival_City_longitude) {
longitude = Arrival_City_longitude + (num%count) * getLongitudeStep();
latitude = Arrival_City_latitude + (num%count) * getlatitudeStep();
} else {
longitude = Depart_City_longitude - (num%count) * getLongitudeStep();
latitude = Depart_City_latitude - (num%count) * getlatitudeStep();
}
System.out.println("longitude: " + longitude);
System.out.println("latitude: " + latitude);
String strLongitude = integer2HexString(new Double(longitude*1000000).intValue());
String strLatitude = integer2HexString(new Double(latitude*1000000).intValue());
System.out.println("strLongitude: " + strLongitude);
System.out.println("strLatitude: " + strLatitude);
SimpleDateFormat sdf = new SimpleDateFormat(dateFormate);
long time = System.currentTimeMillis();
try {
time = sdf.parse(baseTime).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
// 每次上報報文的時間,隨著執行緒號每次遞減1000毫秒,保證間隔1秒的頻率傳送報文
String strTime = sdf.format(time - num*1000);
System.out.println( strTime);
String msg = beginMsg + strLatitude + strLongitude + midMsg + strTime + endMsg;
return msg;
}
}
// 透過上下文獲取JMeter正在執行的執行緒號
int threadNum = ctx.getThreadNum();
log.info("當前執行緒號: " + threadNum);
String msg = Baowen.getLocationMsg(threadNum);
log.info("報文: " + msg);
// 透過內建的vars物件,把報文放入變數容器中,變數的key為msg,供後面的指令碼使用
vars.put("msg", msg);
說明:
1、對時間的處理:以基準時間為參考,每次上報報文的時間,隨著執行緒號的遞增,每次遞減1000毫秒,這樣可以保證間隔1秒的頻率傳送報文。
2、對位置的處理:設定往返的兩個地點,每次上報一個位置,經緯度都按照指定的步頻變化,當經緯度等於或超過終點時,又從終點開始返回,這樣來模擬兩個城市之間往返。
3、最後把結果放入JMeter的變數容器中,後續指令碼只需以“${msg}”就可以引用該變數(如果獲取不到,需要vars.get("msg "))。
(4)新增TCP取樣器
線上程組上右鍵->新增->取樣器->TCP取樣器:
由於本次測試的是TCP服務,所以這樣需要新增一個TCP取樣器。TCP取樣器配置如下:
TCPClient classname:填寫TCP報文格式,有三類,這裡選擇org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl,是常用的十六進位制報文格式。
Re-use connection:複用TCP長連線請求。TCP長連線的時候需要勾選它。
EOL(行尾位元組值):報文結束標誌。因為報文是16進位制的,報文的結束標誌字元是7e ,7e的二進位制是 0111 1110,對應的十進位制是126。
(5)新增察看結果樹
線上程組上右鍵->新增->監聽器->察看結果樹:
(6)新增聚合報告
線上程組上右鍵->新增->監聽器->聚合報告:
3.測試結果
點選執行按鈕,結果如下:
透過聚合報告可知,請求全部傳送成功,並且得到正確的響應。透過察看結果樹,對比不同的TCP取樣器,可以看到請求報文的差異:
報文003:020040220189860422061980267062000100000000000000030131b5eb069383d8000B00020111200609153141010400000000EE7E
報文004:020040220189860422061980267062000100000000000000030131b59606938426000B00020111200609153140010400000000EE7E
4.Bean Shell的應用場景
以上介紹的是自定義函式場景下對Bean Shell的使用。事實上,Bean Shell還有其他的應用場景。
(1)引用外部Java檔案
如果已經有了現成的Java檔案,或者需要從外部Java檔案中呼叫方法,那麼可以使用Bean Shell引入Java檔案,在指令碼中使用。
比如:現有一個Java檔案,名為MyJavaFile.java,在Bean Shell指令碼中可以這樣使用:
// 引入外部Java檔案
source("D:/script/MyJavaFile.java")
// 呼叫Java檔案中的方法
String result = new Baowen().getLocation();
// 儲存變數
vars.put("msg", result);
在bean shel中透過source("程式碼絕對路徑")的方式引入java,然後就和普通的Java類一樣呼叫其方法就行。
(2)引用外部class檔案
這種方式跟上一種類似,先用addClassPath("class檔案所在的目錄")引入 class檔案,然後再用“import包名.類名“的方式匯入類,接下來就可以呼叫class檔案當的類和方法了:
// 引入外部class檔案
addClassPath("D:\\")
// 匯入包和類
Import MyPackeage.Baowen;
// 呼叫Java檔案中的方法
String result = new Baowen().getLocation();
// 儲存變數
vars.put("msg", result);
(3)引用外部Jar包
外部Jar包要先匯入測試中,可以透過兩種方式進行匯入。其一,是在測試計劃中,透過瀏覽按鈕,將需要匯入的jar包引入。
另外,也可以把Jar包放在JMeter安裝目錄|lib\ext下。
然後在Bean Shell中引用:
// 匯入包和類
Import MyPackeage.Baowen;
// 呼叫Java檔案中的方法
String result = new Baowen().getLocation();
// 儲存變數
vars.put("msg", result);
Bean Shell是一個小型的、免費的、嵌入式的Java原始碼直譯器,具有物件指令碼語言特性,能夠動態地執行標準JAVA語法。並且,Bean Shell支援“鬆散的”或者動態地指定型別型別。能夠在執行時做型別檢查,而不需要先定義變數以及指定特定的變數型別來指向變數。
因為Bean Shell是用java寫的,執行在同一個虛擬機器的應用程式,因此可以方便地引用指令碼中的物件,能夠滿足複雜的引數化需求。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31407649/viewspace-2770167/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 效能測試學習筆記:Loadrunner如何進行引數化?筆記
- jmeter使用csv進行引數化(一)JMeter
- jmeter使用csv進行引數化(二)JMeter
- 使用 jMeter 對 SAP Spartacus 進行併發效能測試JMeter
- 一條Jmeter效能測試精通之路影片(52集乾貨)JMeter
- Jmeter模板化引數併發測試JMeter
- 乾貨分享▏軟體效能測試包括哪些測試內容?
- 效能測試進階實踐篇:10分鐘教你使用JMeter進行websocket測試!JMeterWeb
- 使用JMeter進行壓力測試JMeter
- 如何使用jMeter對某個OData服務進行高併發效能測試JMeter
- 使用 JUnit 5.7 進行引數化測試:深入瞭解 @EnumSource
- JMeter 如何與 MySQL 進行整合測試JMeterMySql
- 實用測試技能分享:jmeter+Jenkins效能測試自動化搭建JMeterJenkins
- 使用Loadrunner進行效能測試
- jmeter 效能測試入門手冊分享JMeter
- Jmeter效能測試簡單使用JMeter
- JMeter效能測試JMeter
- 使用 Sysbench 進行 Linux 效能測試Linux
- 使用Jmeter進行效能測試實戰:詳解HTTP請求和JDBC request進階篇JMeterHTTPJDBC
- 使用jMeter構造大量併發HTTP請求進行微服務效能測試JMeterHTTP微服務
- 使用JMeter進行負載測試快速入門JMeter負載
- 軟體測試學習資料——Jmeter引數化2JMeter
- 軟體測試學習資料——Jmeter引數化1JMeter
- JMeter效能測試工具使用入門JMeter
- 乾貨分享 | PCB測試點的用途
- Jmeter介面測試+效能測試JMeter
- 乾貨收藏 | 如何優化前端效能?優化前端
- jmeter之效能測試JMeter
- jmeter做效能測試JMeter
- linux環境下使用jmeter進行分散式測試LinuxJMeter分散式
- 『動善時』JMeter基礎 — 24、JMeter中使用“使用者引數”實現引數化JMeter
- Jmeter效能測試 —— jmeter之使用ServerAgent監控伺服器JMeterServer伺服器
- 好程式設計師Java教程分享Jmeter效能測試程式設計師JavaJMeter
- 【學員乾貨】App常見效能測試點APP
- jmeter之效能測試(16.1)JMeter
- Jmeter效能測試實戰JMeter
- 如何用 JMeter 編寫效能測試指令碼?JMeter指令碼
- Jmeter效能測試:高併發分散式效能測試JMeter分散式