一、什么是Bean Shell
- BeanShell是一種完全符合Java語法規范的腳本語言,並且又擁有自己的一些語法和方法;BeanShell是一種松散類型的腳本語言(這點和JS類似);
- BeanShell是用Java寫成的,一個小型的、免費的、可以下載的、嵌入式的Java源代碼解釋器
- BeanShell能夠動態地執行標准JAVA語法,並利用在JavaScript和Perl中常見的的松散類型、命令、閉包等通用腳本來對其進行拓展。BeanShell不僅僅可以通過運行其內部的腳本來處理Java應用程序,還可以在運行過程中動態執行java應用程序執行java代碼。因為BeanShell是用java寫的,運行在同一個虛擬機的應用程序,因此可以自由地引用對象腳本並返回結果。
- BeanShell執行標准Java語句和表達式,另外包括一些腳本命令和語法。
jmeter中,Beanshell使用與java請求的區別?
要根據自己的使用場景來選擇適合自己的自定義腳本的方式。
BeanShell腳本編寫類似於Java腳本。它可以獲取、修改系統定義或用戶定義的變量值,同時也可以進行一些相應的測試數據處理工作(例如:前置處理器、后置處理器及響應斷言中均存在響應的BeanShell應用)。
使用建議 BeanShell是JMeter內置的功能,但是由於它是腳本語言,動態加載執行的,因此效率不是很高,不太適合於在經常執行的場景下,比如將BeanShell放在循環內部,不斷地被執行。比較適合的應用場景是放在執行一次、或者少數幾次的地方,比如在循環外部讀取配置文件內容等。
Java擴展JMeter的實現方式的效率比較高,適合於放在經常執行的測試步驟中,但是由於它不是JMeter內置的功能,擴展起來需要有些工作量,而且部署的時候也比較麻煩(分布式運行的時候需要將自定義的JAR拷貝至所有的機器上)。
從java請求與beanshell請求的原理來考慮:
1、比如測試java接口,確不想繼承AbstractJavaSamplerClient,可以考慮用beanshell請求來完成。
2、對數據進行參數化時,比如要對字符串進行加密操作、拼成unique類型的ID、定制時間類型等等,可以用beanShell來完成。
3、線程之間想共享一個變量,可以用beanShell實現。
二、Jmeter有哪些Bean Shell
-
定時器: BeanShell Timer 可用來設置線程延遲間隔
-
前置處理器:BeanShell PreProcessor
-
采樣器: BeanShell Sampler
-
后置處理器:BeanShell PostProcessor
-
斷言: BeanShell斷言
-
監聽器: BeanShell Listener
這幾種在使用是時比較類似,只需要用一種重點練習用法就可以。
三、用法
BeanShell PreProcessor用法(對參數值加密處理返回結果)
常用內置變量
目錄
一、操作變量
二、操作屬性
三、自定義函數
四、引用外部java文件
五、引用外部class文件
六、引用外部Jar包
七、其它用法(接受參數, log等)
3、用法簡單總結
1)可使用用戶自定義的變量,在simple中對其進行處理(諸如對其加密、類型轉換等),后續請求值使用這些變量與定義函數值;
2)可以在simple中java直接自定義函數,對其一系列處理后,后續請求值使用這些變量與定義函數值;
四、使用案例
案例一:使用Jmeter的BeanShell斷言,把響應數據中的JSON跟數據庫中的記錄對比
案例二:jmeter beanShell 修改http請求參數
案例三:JMeter - BeanShellSampler實現本地AES加密、Jmeter接口測試加解密及Bean Shell使用案例
md5加密
import org.apache.commons.codec.digest.DigestUtils; //導入md5加密的包 String str = "1234567"; //要加密的字符串 String md5_after = DigestUtils.md5Hex(str); // md5加密 vars.put("md5_upper",sign.toUpperCase()); //把加密的結果轉成大寫的,存到md5_upper這個變量里面,參數化的時候直接用${md5_upper}取值就ok了 vars.put("md5_lower",sign.toLowerCase()); //把加密的結果轉成小寫的,存到md5_lower這個變量里面,參數化的時候直接用${md5_lower}取值就ok了 vars.put("befor_md5",str); //這個是 加密之前的字符串,在beanshell里面定義的變量參數化的時候不能直接使用,需要用vars.put方法才可以用
如果用到簽名算法時,可參考:大眾點評API
簽名算法類似如下:
1. 對除appkey以外的所有請求參數進行字典升序排列;
2. 將以上排序后的參數表進行字符串連接,如key1value1key2value2key3value3...keyNvalueN;
3. 將app key作為前綴,將app secret作為后綴,對該字符串進行SHA-1計算,並轉換成16進制編碼;

import org.apache.commons.codec.digest.DigestUtils; import java.util.Map; import java.util.HashMap; import java.util.Map.Entry; // 定義Secret String secret = "test"; // 創建參數表 //Map<String, String> paramMap = new HashMap<String, String>(); Map paramMap = new HashMap(); paramMap.put("mobileNumber", "${mobileNumber}"); paramMap.put("loginPword", "test123456"); paramMap.put("time", "${__time(/1000,)}"); paramMap.put("geetest_challenge", ""); paramMap.put("geetest_seccode", ""); paramMap.put("geetest_validate", ""); // 對參數名進行字典排序 String[] keyArray = paramMap.keySet().toArray(new String[0]); Arrays.sort(keyArray); // 拼接有序的參數名-值串 StringBuilder stringBuilder = new StringBuilder(); for (String key : keyArray) { stringBuilder.append(key).append(paramMap.get(key)); } stringBuilder.append(secret); String s = stringBuilder.toString(); // md5加密 String sign = DigestUtils.md5Hex(s); vars.put("sign",sign);
第一步:測試計划添加自定義變量
第二步:添加beanshell請求,處理
第三步:查看結果樹,查看結果

result = "\n1:"+bsh.args[0]+"\n"; //1:從參數框中獲取參數變量,不適用 result+="2:${testBeanshell}\n"; //2:直接獲取變量,操作方便,非常適用 result+="3:"+vars.get("testBeanshell"); //3:從vars內置變量中獲取變量,適用 vars.put("testBeanshell","beanshell_change");//改變變量值 result+="\n4:${testBeanshell}";//4:直接獲取不生效,因為jmeter還沒有對其進行復制 result+="\n5:"+vars.get("testBeanshell");//:5:值改變,容易理解 ResponseCode = 500;//回寫請求響應代碼,借鑒的http響應碼 ResponseMessage = "test ok!!";//回寫響應信息 IsSuccess = true;//回寫響應結果 log.info("\nlog test:"+result);//調用jmeter內置log對象,日志會打印到jmeter.log中 SampleResult.setResponseData("SampleResult:"+result+"\n");//回寫響應數據,SampleResult為jmeter內置回寫結果對象,有很多可用方法,可以參看源碼 return "return:"+result;//這里的返回值,相當於調用SampleResult.setResponseData()方法,注意使用的return關鍵字,后面的行都不會執行,且SampleResult.setResponseData("SampleResult:"+result+"\n");也不會執行,這里會被return的結果覆蓋。但是用SampleResult.setResponseData()方法回寫,后續還可以接代碼行,因此建議不用return進行回寫響應數據。
紅色標注的為入參。可以直接用seling OK中間用空格分開,或用${}來引用。腳本中通過bsh.args來引用,bsh.args[0]表示取的第一個值。
能訪問的屬性與變量:
SampleResult:訪問對應的結果對象,能查詢與編輯其中的屬性。
ResponseCode:引用自行設置的返回碼。
ResponseMessage:設置響應消息內容。
IsSuccess:引用它來決定產生的事務是否成功。如果設置為false那事務會失敗。那在結果樹與聚合報告中都會顯示失敗。
案例五:jmeter使用BeanShell Sampler測試自己寫的java接口(一)
案例:起多個本地線程jmeter beanshell使用說明
案例:jmeter之編寫java請求一beashell調用java代碼(上篇)(推