BeanShell是一种完全符合Java语法规范的脚本语言,是轻量级的Java脚本,所以BeanShell和Java是可以无缝衔接的。
BeanShell的特点:
1、完整的Java语法的动态执行,Java代码片段,以及松散类型的Java和其他脚本
2、透明地访问所有Java对象和API
Java对格式的要求很严格,必须按照规定的格式编写,编译时才能通过,个人建议不要直接在jmeter beanshell里写,先在java编辑器里写好调试没有问题后,再粘贴到jmeter beanshell里,需要注意的是jmeter beanshell里是不支持"System.out.println"等操作的,如果在java编辑器里调试调试、需要引用就meter相关jar包(在sampler教程里有讲到)
那么Jmeter中有哪些BeanShell?
1、定时器:BeanShell Timer
2、前置处理器:BeanShell PreProcessor
3、采样器:BeanShell Sampler
4、后置处理器:BeanShell PostProcessor
5、断言:BeanShell Assertion
6、监听器: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表示的当前请求的信息! prev - (SampleResult):获取前面的sample返回的信息,常用方法: a) getResponseDataAsString():获取响应信息 b) getResponseCode() :获取响应code |
| data | 类型是byte[],即字节数组, 当前请求的响应数据,可以用String str = new String(data, "utf-8")转成字符串再打印出来 |
本文主要讲解下,beanshell前置处理器、后置处理器、和断言
1.前置处理器
假设现在有一个登录HTTP接口,且这个登录接口对密码做了Base64加密,这个时候我们要测试这个登录接口,就可以使用BeanShell前置处理器 ,先利用脚本将密码做Base64加密,HTTP采样器中再使用密码这个变量的值

BeanShell PostProcessor
BeanShell后置处理器,可以用于处理响应数据。比如现在有一个接口返回的数据里,我只需要拿到id,那么就可以在后置处理器里先处理response。或者接口返回的数据是加密的,也可以在后置处理器里先对响应数据做解密。

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,json |
可以看到BeanShell断言同样可以实现修改响应数据,不过修改响应数据还是放在BeanShell后置处理器中比较好,不同的元件负责不同的功能,断言就只做断言判断。
现在我们用ResponseCode来判断,等于200时,设置为断言失败,写入如下代码:
if ("222".equals(""+ResponseCode) == false )
{
// 响应码不等于200时,设置断言失败,并输出失败信息
Failure=true ;
FailureMessage ="Response code was not a 200 response code it was " + ResponseCode + "." ;
log.info( "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;
}
结果树

beanshell使用示例
实现一个登陆成功后返回信息解密出授权串给其他接口使用
思路
1.参数加密发送请求
需要利用JSONObject或者JSONArray构造JSON对象,进行加密
Gson gson = new Gson();
Map params = new HashMap(); // beanshell 中不能指定数据类型String encryptedStr = AesCrypto.xxxxxx(gson.toJson(params));
vars.put("params",encryptedStr);
2.获取请求的返回值,即Json响应;
String response_data = prev.getResponseDataAsString(); //注意此处获取到的是String类型;
3.利用上一步获取的字符串形式的JSON,结合Java处理Json的方法,将需要的键值提取出来;
tring access_token_second = AesCrypto.xxxx(vars.get("access_token_second"));
JsonObject returnData = new JsonParser().parse(access_token_second).getAsJsonObject();
String access_token = returnData.get("access_token").toString().replace("\"", "");//需要去除字符串两端引号
String uid = returnData.get("uid").toString();
3.解析生成认证信息后,用于下一个请求的参数化值;
//生成认证信息
String basic = Crypto.getBasicAuth(uid,jiami_access_token);
log.info("basic-------------------"+basic);
//存储认证信息
vars.put("token",basic);
前置条件
1.打好加密解密jar包,导入jmeter\lib\ext下,并将该jar包添加到测试计划的Library中
2.将gson.jar、commons-codec-1.12.jar包置于..\jmeter\lib\ext下,并将该jar包添加到测试计划的Library中;否则会报:Typed variable declaration : Class: JSONObject not found in namespace的错误;

创建前置前置beanshell
调用AesCrypto、Gson等方法对登录参数进行加密,保存

创建请求sampler
请求时调用params参数

后置处理器解析出access_token,并生成认证信息
1.获取登录成功返回值


2.解析出access_token,并生成认证信息

其它接口使用授权信息
1.请求头里调用授权信息

2.发送请求

3.请求结果

beanshell 解析json array
import org.json.*;
vars.put("addressNum","0");
String response_data = prev.getResponseDataAsString();
log.info(response_data);
JSONObject JsonData = new JSONObject(response_data);
JSONArray data_array = JsonData.getJSONArray("data");
int len = data_array.length();
String strlen = Integer.toString(len);
vars.put("addressNum",strlen);
//log.info("%%%%%%%%%%%%%%%%%%%%%%%"+data_array);
for(int i = 0;i < len;++i)
{
log.info("(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((("+i);
JSONObject jsonTemp = data_array.getJSONObject(i); //获取 data[ i ] 数组对象;
log.info(jsonTemp.toString());
String StrData = jsonTemp.get("addrId").toString();
log.info("-------------------------------------------------------------------------"+StrData);
vars.put("addrId_"+i,StrData);
}




Comments | NOTHING