beanshell是什么
BeanShell是一個小型嵌入式Java源代碼解釋器,具有對象腳本語言特性,能夠動態地執行標准JAVA語法,並利用在JavaScript和Perl中常見的的松散類型、命令、閉包等通用腳本來對其進行拓展。BeanShell不僅僅可以通過運行其內部的腳本來處理Java應用程序,還可以在運行過程中動態執行你java應用程序執行java代碼。因為BeanShell是用java寫的,運行在同一個虛擬機的應用程序,因此可以自由地引用對象腳本並返回結果。(摘抄自網絡)
下載及運行
下載地址:https://beanshell.github.io/download.html
java -jar直接運行
測試

其它方式啟動:先把jar包加入到環境變量

界面UI方式 :java bsh.Console



命令行方式 :java bsh.Interpreter
運行腳本文件:java bsh.Interpreter filename [args]
第二個例子

運行結果
如果jar包沒加到環境變量,可以這樣運行:java -classpath %CLASSPATH%;bsh-2.0b4.jar bsh.Interpreter test.txt

常用命令
print() 輸出內容到命令行中
source()讀一個bsh腳本到當前解釋器(interpreter)中,或者在新的解釋器中運行這個腳本
而我們的jmeter中,已經自帶了jar包,下面介紹jmeter中如何使用beanshell
添加變量

引用變量

發送請求,可以看到密碼加密了

自定義函數
上面也可以封裝為函數
下面方法返回類型為void
import org.apache.commons.codec.digest.DigestUtils;
public static void fun(){
String password_md5 = DigestUtils.md5Hex("123456");
vars.put("password_md5", password_md5);
}
fun();
下面方法返回類型為String
import org.apache.commons.codec.digest.DigestUtils;
public static String fun(){
String password_md5 = DigestUtils.md5Hex("123456");
print(password_md5); // 在命令行窗口打印結果
return password_md5;
}
String password_md5 = fun();
vars.put("password_md5", password_md5);
也可以寫成這樣(方法不寫返回類型)
import org.apache.commons.codec.digest.DigestUtils;
fun(){
String password_md5 = DigestUtils.md5Hex("123456");
print(password_md5); // 在命令行窗口打印結果
return password_md5;
}
String password_md5 = fun();
vars.put("password_md5", password_md5);

甚至寫成這樣(定義的變量也沒類型)
import org.apache.commons.codec.digest.DigestUtils;
fun(){
String password_md5_res = DigestUtils.md5Hex("123456");
print(password_md5_res); // 在命令行窗口打印結果
return password_md5_res;
}
password_md5 = fun();
vars.put("password_md5", password_md5);
但是還是推薦按照java的方式寫,嚴格定義。
引用java文件、class文件、jar文件
常用內置變量
JMeter在它的BeanShell中內置了變量,用戶可以通過這些變量與JMeter進行交互。
log vars prev Failure FailureMessage
具體用法請百度,本篇的示例中也有使用到。
beanshell組件
Jmeter中包括多種BeanShell,用法差不多,只是作用的地方不同。
定時器: BeanShell Timer
前置處理器:BeanShell PreProcessor,提前處理請求參數,如:加密解密等
采樣器: BeanShell Sampler
后置處理器:BeanShell PostProcessor,在請求后對返回結果進行處理
斷言: BeanShell斷言,驗證返回結果的正確性
監聽器: BeanShell Listener
下面舉例幾個常用的。
beanshell采樣器

引用變量

發送請求,可以看到密碼加密了

beanshell前置處理器

beanshell斷言
pom依賴
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>
</dependencies>
代碼及打的jar包

把jar包復制到jmeter的lib下ext中,重啟jmeter
添加用戶定義變量

請求

beanshell前置處理器,加密密碼

beanshell斷言

完整腳本
import com.uncleyong.JsonToJSONObject;
import com.alibaba.fastjson.JSONObject; // 不能少,下面定義了JSONObject類型
print("===========開始執行==========");
String exp_result = vars.get("exp_result");
print("exp_result= " + exp_result);
print("exp_result的類型:" + exp_result.getClass().toString()); // exp_result的類型:class java.lang.String
//Integer.valueOf返回的是Integer對象,Integer.parseInt返回的是int
Integer exp_result2 = Integer.valueOf(exp_result);
print("exp_result2的類型:" + exp_result2.getClass().toString()); // exp_result2的類型:class java.lang.Integer
String jsonString = prev.getResponseDataAsString();
print("獲取到的返回結果:" + jsonString);
print("返回結果的類型:" + jsonString.getClass().toString()); // 返回結果的類型:class java.lang.String
JSONObject responseJson = new JsonToJSONObject().JSONObjectUtil(jsonString);
print("轉換后的返回結果:" + responseJson);
print("轉換后的返回結果類型:" + responseJson.getClass()); // 轉換后的返回結果類型:class com.alibaba.fastjson.JSONObject
String code = responseJson.getString("code");
print("code = " + code);
print("code的類型:" + code.getClass()); // code的類型:class java.lang.String
Integer code2 = responseJson.getInteger("code");
print("code2 = " + code2);
print("code2的類型:" + code2.getClass()); // code2的類型:class java.lang.Integer
//if (code.equals(exp_result)==false) {
if (code2 != exp_result3) {
print("--------進入if語句--------");
Failure = true;
FailureMessage = "code與實際值不一致,期望值" + exp_result + ", 實際值" + code;
}
print("===========結束執行==========");
運行結果


手把手實踐
《jmeter對接口測試入參進行MD5加密的5種方式》,詳見微信公眾號:全棧測試筆記
https://www.cnblogs.com/uncleyong/protected/p/9429752.html
《性能測試:jmeter中通過beanshell把關聯轉變成參數化》
https://www.cnblogs.com/uncleyong/p/10986466.html
