概述
BeanShell是一個小型嵌入式Java源代碼解釋器,具有對象腳本語言特性,能夠動态地執行标準JAVA文法,并利用在JavaScript和Perl中常見的的松散類型、指令、閉包等通用腳本來對其進行拓展。BeanShell不僅僅可以通過運作其内部的腳本來處理Java應用程式,還可以在運作過程中動态執行你java應用程式執行java代碼。因為BeanShell是用java寫的,運作在同一個虛拟機的應用程式,是以可以自由地引用對象腳本并傳回結果
beanshell在jmeter中展現有:BeanShell PreProcessor、BeanShell Sampler、BeanShell PostProcessor、__BeanShell函數、BeanShell Timer 、BeanShell斷言、BeanShell Listener,在這裡都是可以直接return的。
注意:BeanShell Timer 、BeanShell斷言、BeanShell Listener在此不做詳細介紹,使用前面幾個舉例子
BeanShell PreProcessor内置變量
- log:用來記錄日志檔案,寫入到jmeber.log檔案,參考 org.apache.log.Logger
官網給出是slf4j.Logger 我查檢查了jar包,沒有發現什麼異常,如果有哪位發現是什麼問題,請指正
- ctx:(JmeterContext)通過它來通路context,參考:org.apache.jmeter.threads.JMeterContext
-
vars - (JMeterVariables):操作jmeter變量,提供讀取/寫入通路變量的方法。參考org.apache.jmeter.threads.JMeterVariables
這個變量實際引用了JMeter線程中的局部變量容器(本質上是Map),它是測試用例與BeanShell互動的橋梁
- props - (JMeterProperties - class Java.util.Properties):操作jmeter屬性,該變量引用了JMeter的配置資訊,可以擷取Jmeter的屬性,它的使用方法與vars類似,但是隻能put進去String類型的值,而不能是一個對象。對應于java.util.Properties。
- prev:擷取前面的sample采樣的結果,參考:org.apache.jmeter.samplers.SampleResult
- sampler: 通路目前采樣,參考 org.apache.jmeter.samplers.Sampler
在測試計劃中建立一個前置處理器(beanshell preProcessor),編寫如下腳本,能涵蓋到正常用法,更詳細的請參考對API
//log:org.apache.log.Logger 常用
log.info("message info");
log.debug("message debug");
//log.error("message error");
log.warn("message warn");
//ctx:org.apache.jmeter.threads.JMeterContex
log.info("sample name:"+ctx.getCurrentSampler().getName());
//vars:org.apache.jmeter.threads.JMeterVariables
String string = "hello world";
byte[] bytes = string.getBytes();
vars.putObject("testObj",bytes);
vars.put("test","abc");
byte[] res=(byte[])vars.getObject("testObj");
for(int i=;i<res.length;i++){
log.info("vars.get(\"testObj\")["+i+"]="+res[i]);
}
log.info("vars.get(\"test\")="+vars.get("test"));
//prev:org.apache.jmeter.samplers.SampleResult
//這裡是擷取前一個取樣器的結果,若沒有,會報空指針,最簡單的辦法線程組至少運作次,第二次即可擷取
try{
log.info("prev.getThreadName()="+prev.getThreadName());
}catch(Exception e){
e.printStackTrace();
}
//sampler:org.apache.jmeter.samplers.Sampler
log.info("sampler.getName()="+sampler.getName());
BeanShell PostProcessor
相對preProcessor,内置變量去掉了sampler,增加data,在此隻說data,其他參考preProcessor
data:儲存response内容,是一個byte[],儲存的是取樣器的結果,一般要對結果做特殊處理的時候使用,比如要取出來後做二次加工或者将部分内容定制化輸出等……
建立BeanShell PostProcessor
System.out.println(ctx.getCurrentSampler().getName()+" ======Start======");
for(int i=;i<data.length;i++){
System.out.print(((char)data[i]).toString());
}
System.out.println(ctx.getCurrentSampler().getName()+" ======End======");
__BeanShell函數
函數裡面寫入響應的表達式,可以引用BeanShell中的變量等,可以直接使用的變量比較多 參考BeanShell Sampler
- log 列印日志 log.info(“在控制台列印日志”);
- SampleResult 擷取SampleResult對象,可以通過這個對象擷取想要的資訊
- Response 擷取Response對象,可以通過這個對象擷取對應的資訊
- Failure 檢視接口調用是否成功,如果傳回false是成功的,true是失敗的
- FailureMessage 失敗資訊,沒有設定的時候失敗資訊是空的。可以set這個資訊
- ResponseData 擷取 response body 類型是byte[]
- ResponseCode 傳回接口code 成功是200
- ResponseMessage 擷取msg 成功是OK
- ResponseHeaders 擷取接口服務端傳回的頭部資訊
- RequestHeaders 擷取用戶端請求的頭部資訊
- SampleLabel 擷取接口請求的名稱
- SamplerData 擷取請求的url和body
- ctx 代表上下文資訊,可以直接使用
- vars 可以直接調用,将擷取的資料變成jmeter變量(put),也可以擷取使用者自定義的變量(get)
栗子
preProcessor、postProcessor、BeanShell函數與普通取樣器傳參
- 建立測試計劃
- 建立beanshell preProcessor
//log:org.apache.log.Logger 常用
log.info("message info");
log.debug("message debug");
//log.error("message error");
log.warn("message warn");
//ctx:org.apache.jmeter.threads.JMeterContex
log.info("sample name:"+ctx.getCurrentSampler().getName());
//vars:org.apache.jmeter.threads.JMeterVariables
String string = "hello world";
byte[] bytes = string.getBytes();
vars.putObject("testObj",bytes);
vars.put("test","abc");
byte[] res=(byte[])vars.getObject("testObj");
for(int i=;i<res.length;i++){
log.info("vars.get(\"testObj\")["+i+"]="+res[i]);
}
log.info("vars.get(\"test\")="+vars.get("test"));
//prev:org.apache.jmeter.samplers.SampleResult
//這裡是擷取前一個取樣器的結果,若沒有,會報空指針,最簡單的辦法線程組至少運作次,第二次即可擷取
try{
log.info("prev.getThreadName()="+prev.getThreadName());
}catch(Exception e){
e.printStackTrace();
}
//sampler:org.apache.jmeter.samplers.Sampler
log.info("sampler.getName()="+sampler.getName());
return "測試而已,在此可有可無";
- 建立beanshell postProcessor
System.out.println(ctx.getCurrentSampler().getName()+" ======Start======");
for(int i=;i<data.length;i++){
System.out.print(((char)data[i]).toString());
}
System.out.println(ctx.getCurrentSampler().getName()+" ======End======");
-
建立BeanShell Sampler
在該案例中直接傳回,不寫任何内容
- 建立線程組并建立http請求 設定運作兩次
jmeter應用-----beanshell的使用概述 參數kw的值是BeanShell表達式,取值為在preProcessor中放入的參數testObj
參數test的值是普通表達式,取值為在preProcessor中放入的參數test
jmeter應用-----beanshell的使用概述
beanshell中可以寫更複雜的例子如定義方法,引入外部類等
引入外部類幾種方式
- 複雜的打成jar
- 在測試計劃中引入jar
- 把jar所在路徑加入到可執行路徑 addClassPath()
- 簡單的單類也可以使用source()引入
孤立的類
public class JmeterBeanShellSourceTest {
public static int add(int a,int b) {
return a+b;
}
public void sayhello(String name) {
System.out.println("source hi "+name);
}
}
打成jar包
/**
* @Title: JmeterBeanShellTest.java
* @Package com.dangdang
* @Description: TODO
* @author yueling [email protected]
* @date 2018年6月29日 下午1:09:50
* @version V1.0
*/
package com.dangdang;
/**
* @ClassName: JmeterBeanShellTest
* @Description: TODO
* @author yueling
* @date 2018年6月29日 下午1:09:51
*
*/
public class JmeterBeanShellTest {
public static int add(int a,int b) {
return a+b;
}
public void sayhello(String name) {
System.out.println("hi "+name);
}
}
在之前的測試計劃上做如下修改:
- 引入jar包
- 修改BeanShell PreProcessor
import com.dangdang.JmeterBeanShellTest;
//log:org.apache.log.Logger 常用
log.info("message info");
log.debug("message debug");
//log.error("message error");
log.warn("message warn");
//ctx:org.apache.jmeter.threads.JMeterContex
log.info("sample name:"+ctx.getCurrentSampler().getName());
//vars:org.apache.jmeter.threads.JMeterVariables
String string = "hello world";
byte[] bytes = string.getBytes();
vars.putObject("testObj",bytes);
vars.put("test","abc");
byte[] res=(byte[])vars.getObject("testObj");
for(int i=;i<res.length;i++){
log.info("vars.get(\"testObj\")["+i+"]="+res[i]);
}
log.info("vars.get(\"test\")="+vars.get("test"));
//prev:org.apache.jmeter.samplers.SampleResult
//這裡是擷取前一個取樣器的結果,若沒有,會報空指針,最簡單的辦法線程組至少運作次,第二次即可擷取
try{
log.info("prev.getThreadName()="+prev.getThreadName());
}catch(Exception e){
e.printStackTrace();
}
//sampler:org.apache.jmeter.samplers.Sampler
log.info("sampler.getName()="+sampler.getName());
source("d:\\JmeterBeanShellSourceTest.java");
int sourceresult=JmeterBeanShellSourceTest.add(,);
JmeterBeanShellSourceTest jmeterBeanShellSourceTest = new JmeterBeanShellSourceTest();
jmeterBeanShellSourceTest.sayhello("tom");
log.info("source result="+String.valueOf(sourceresult));
JmeterBeanShellTest jmeterBeanShellTest = new JmeterBeanShellTest();
int result=jmeterBeanShellTest.add(,);
jmeterBeanShellTest.sayhello("tom");
log.info("result="+String.valueOf(result));
return "測試而已,在此可有可無";