天天看點

jmeter應用-----beanshell的使用概述

概述

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 "測試而已,在此可有可無";