十七、Jmeter BeanShell使用


 
 
 
 
 

一、什么是Bean Shell

  • BeanShell是一種完全符合Java語法規范的腳本語言,並且又擁有自己的一些語法和方法;
  • BeanShell是一種松散類型的腳本語言(這點和JS類似);
  • BeanShell是用Java寫成的,一個小型的、免費的、可以下載的、嵌入式的Java源代碼解釋器,具有對象腳本語言特性,非常精簡的解釋器jar文件大小為175k。
  • BeanShell執行標准Java語句和表達式,另外包括一些腳本命令和語法。
    官網:http://www.BeanShell.org/

二、Jmeter有哪些Bean Shell

    • 定時器: BeanShell Timer
    • 前置處理器:BeanShell PreProcessor
    • 采樣器: BeanShell Sampler
    • 后置處理器:BeanShell PostProcessor
    • 斷言:BeanShell斷言
    • 監聽器:BeanShell Listener

三、BeanShell內置對象

其中,每個BeanShell元件都有自己的內置對象,在元件上也有對應說明,當前元件的內置對象有哪些,比如BeanShell Sampler元件的底部有提示該元件有哪些內置對象。

這里先介紹常用的內置對象。

 

log 記錄日志,Jmeter使用log4j記錄日志,一般使用的比較多的是log.info()、log.error(),打印的日志會記錄到bin/jmeter.log文件
props 操作Jmeter屬性,即jmeter.properties文件的配置
  props.get("https.use.cached.ssl.context"): 獲取對應的屬性值
  props.put("https.use.cached.ssl.context", false): 保存數據到Jmeter屬性中,如果屬性不存在就創建
vars 是類JMeterVariables的對象,具體內部方法使用,請看 
操作Jmeter變量,需要注意Jmeter變量是在線程啟動時,拷貝到線程的,類似線程的局部變量,所以一個線程更新了變量,不會影響到另一個線程
  vars.get("name"): 從線程中獲得變量值
  vars.put("key", "value"): 保存數據到線程中,如果變量不存在會創建
ctx 是類JMeterContext的對象,保存線程的上下文,該對象不是線程安全的,建議在單線程時使用,具體內部方法使用,請看
prev 是類SampleResult的對象,保存前一個請求的信息,具體內部方法使用,請看 
注意
根據作用域和執行順序 可以知道,元件有在采樣器前執行的,有在采樣器后執行的,對於在采樣器前執行的,prev表示的是前一個請求的信息,而對於在采樣器后執行的,prev表示的當前請求的信息!
data 類型是byte[],即字節數組,
當前請求的響應數據,可以用String str = new String(data, "utf-8")轉成字符串再打印出來

四、常見BeanShell 元件介紹

1.BeanShell Sampler

 
Reset bsh.Interpreter before each call(2):勾選后,線程每次循環前重置變量。但這個我勾選了之后,循環也沒有重置變量。不知道是不是Jmeter文檔沒更新的原因。
Parameters(3):傳遞給BeanShell腳本的參數,只能傳遞String字符串類型。有兩種方式使用:
          Parameters:單個字符串,則使用Parameters;
          bsh.args:數組,空白處分割,比如a b c,那么bsh.args[0]=a。
Script file(4):包含要運行的BeanShell腳本的文件,文件名存儲在變量FileName中,添加了腳本文件后,就只會運行添加的腳本文件,Script部分的腳本代碼不會運行了。
Script(5):要運行的BeanShell腳本,返回值如果不為null,就存儲為采樣器結果。
內置對象(6):

 

SampleResult 是類SampleResult的對象,保存當前請求和響應的信息,具體內部方法使用,請看
ResponseCode 響應的status code,默認為200
ResponseMessage 響應信息,默認為"OK"
IsSuccess 請求是否成功,默認為true
Label 采樣器的標簽,即Name字段
FileName 文件名,如果Script file有包含外部bsh文件

2.BeanShell PreProcessor

假設現在有一個登錄HTTP接口,且這個登錄接口對密碼做了Base64加密,這個時候我們要測試這個登錄接口,就可以使用BeanShell前置處理器  ,先利用腳本將密碼做Base64加密,HTTP采樣器中再使用密碼這個變量的值。
Reset bsh.Interpreter before each call(1):和BeanShell Sampler中的2一樣,True表示勾選。

內置對象(4):

 

sampler 是類Sampler的對象,表示當前采樣器
 

3.BeanShell PostProcessor

BeanShell后置處理器,可以用於處理響應數據。比如現在有一個接口返回的數據數據是加密的,也可以在后置處理器里先對響應數據做解密。

如果我們要認為修改響應數據,那么就可以通過prev這個對象來修改,prev是SampleResult的對象,查看SampleResult類的文檔,可以看到一個方法:

那么我們現在就通過BeanShell PostProcessor來將接口的返回數據修改為"Hello, World",寫入如下代碼:
byte[] b = "Hello,World".getBytes();
prev.setResponseData(b);
 

4.BeanShell Timer

定時器會讓作用域內的每一個采樣器都在執行前等待一個固定的時長,如果作用域內有多個定時器,那這多個定時器就會在采樣器之前全部執行,所以多個定時器的延遲時長是每個定時器的延時時長的累加。

現在,我們想要一個采樣器延遲3秒再執行,寫入如下代碼:

// 單位是毫秒
Thread.sleep(3000);

從日志文件bin/jmeter.log中可以看到采樣器延遲了3秒。

5.BeanShell Assertion

可以看到BeanShell斷言的內置對象很多,可讀/可寫的意思是我們可以更改,比如說SampleResult是當前請求響應的數據,說白了,在BeanShell斷言里同樣可以修改響應數據,和BeanShell后置處理器一樣。

Failure boolean,用來設置斷言狀態,為true,表明斷言失敗
FailureMessage String,用來設置斷言信息
SampleResult SampleResult,具體內部方法,請看
Response SampleResult,具體內部方法,請看
ResponseData byte[],響應數據
ResponseCode String,status code的值,比如200,404
ResponseMessage String,響應信息,比如OK
ResponseHeaders String,響應頭
RequestHeaders String,請求頭
SampleLabel String,采樣器的Name
SamplerData String,就是截圖中的內容

現在我們用ResponseCode來判斷,等於200時,設置為通過,寫入如下代碼:

if ("200".equals(""+ResponseCode) == false )
{
    // 響應碼不等於200時,設置斷言失敗,並輸出失敗信息
    Failure=true ;
    FailureMessage ="Response code was not a 200 response code it was " + ResponseCode + "." ;
    print ( "the return code is " + ResponseCode);   // this goes to stdout
    log.warn( "the return code is " + ResponseCode); // this goes to the JMeter log file
} else {
    // 響應碼等於200時,設置斷言成功,並輸出成功信息
    Failure=false;
    FailureMessage = "Return true, and the response code was " + ResponseCode;
     }

6.BeanShell Listener

內置對象:

 

sampleEvent SampleEvent,具體內部方法,請看

BeanShell監聽器用相比較而言比較少

五、編寫腳本

例如:現在線程有兩個變量username=Augus,new_name=ls,我們需要讀取username將new_name修改為"Hello, Augus"。

1、設置變量username=Augus,new_name=ls:
Jmeter設置變量的方式一共有4種:
1)Test Plan的User Defined Variables,
2)Config Element的User Defined Variables ,
3)Config Element的CSV Data Set Config,
4)Pre Processors的User Parameters
這里就直接使用Test Plan的User Defined Variables了

2、添加一個Sampler --> Debug Sampler,命名為before,其他配置保持默認即可,這只是用來查看變量修改前的值。
3、添加一個Sampler --> BeanShell Sampler,並先寫入如下腳本:
public static void test(){
//定義一個變量
String inout;
//獲取變量aa所對應的值,賦值給input
input = vars.get("username");
String output = "hello," + input;
vars.put("new_name",output);
}

test()

4、添加一個Sampler --> Debug Sampler,命名為after
5、添加一個Listener --> View Results Tree
6、運行,查看結果:

 
上面已經實現了修改變量值,現在我想把這段代碼提取到一個Java的方法里,之后再在BeanShell Sampler中直接使用。
BeanShell中引用外部類,有三種方法:
1)引用源文件,即.java文件。
2)引用字節碼文件,即.class文件。
3)引用jar包,即.jar文件。
現在先新建一個BeanShellMethod.java文件,並寫入如下代碼:
public class BeanShellMethod {
    public static String test(String input) {
        String output = "hello," + input;
        return output;    
    }
}

引用源文件

Jmeter提供了source函數,來引用源文件。在BeanShell Sampler中寫入如下代碼:

//加載使用java文件
source("D:\\jmeterBeanShell\\BeanShellMethod.java");

//獲取變量aa所對應的值
String str1 = vars.get("username");

//調用java文件中test函數,對於
String str2 = new BeanShellMethod().test(str1);

//保存值
vars.put("password",str2);

運行,從after中可以看到new_name變量被修改了。



 

引用字節碼文件

上面我們有了BeanShellMethod.java,可以將其編譯為后綴為.class的字節碼文件,方式如下:

javac BeanShellMethod.java

Jmeter提供了addClassPath函數,來引用字節碼文件。在BeanShell Sampler中寫入如下代碼:

//加載class文件的路徑
addClassPath("D:\\jmeterBeanShell");

//注意這里導入類,注意也有加;
import BeanShellMethod;

//獲取aa變量的值
String str1 = vars.get("username");

//調用test方法
String str2 = new BeanShellMethod().test(str1);

//賦值保存
vars.put("new_name",str2);

運行,從after中可以看到new_name變量被修改了。

引用外部jar包

Jmeter引用外部jar包方法:將jar包拷貝到jmeter/lib/ext目錄下,這種需要重啟Jmeter,才能加載這個jar包;

首先編輯java文件,然后再將.class文件打包成jar包,再將jar包拷貝到對應目錄.然后在BeanShell Sampler中寫入如下代碼:

import hellotest.BeanShellMethod;

//獲取aa變量的值
String str1 = vars.get("username");

//調用test方法
String str2 = new hellotest.BeanShellMethod().test(str1);

//賦值保存
vars.put("new_name",str2);

運行,從after中可以看到new_name變量被修改了。

 

六、其它用法(接受參數, log等)

1、在Test Plan中定義如下三個變量:

2、Bean Shell可腳本如下:

  • a、bean shell可以接受傳入參數,如下圖:${name} ${age} ${sex}
  • b、參數可以通過bsh.args[]按順序提取
  • c、bean shell提供了一個內置變量Parameters,來保存參數的集合
//獲取參數傳遞過來的值並存入變量中
vars.put("v1",bsh.args[0]);
vars.put("v2",bsh.args[1]);
vars.put("v3",bsh.args[2]);

//獲取參數傳遞過來的變量集合
vars.put("v4",Parameters);

//輸出變量集合
log.info(Parameters);

//輸出該元件的name
log.info(Label);

//設置響應代碼
ResponseCode = 500;

//設置響應信息
ResponseMessage = "This is a BeanShell test";

//設置是否成功
IsSucces = false;

//設置響應數據
SampleResult.setResponseData("hello world")

3、運行結果如下圖:

下圖中1輸入的這兩句設置:

ResponseCode = 500;
ResponseMessage = ResponseMessage = "This is a BeanShell test";

下圖中2輸入的這兩句設置:

這里需要注意,點擊【選項】,勾選log Viewer,然后運行,可以查看運行的日志信息

//輸出變量集合
log.info(Parameters);

//輸出該元件的name
log.info(Label);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM