十七、Jmeter BeanShell使用

十七、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元件的底部有提示该元件有哪些内置对象。

img

这里先介绍常用的内置对象。

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

img

Reset bsh.Interpreter before each call(2):勾选后,线程每次循环前重置变量。但这个我勾选了之后,循环也没有重置变量。不知道是不是Jmeter文档没更新的原因。

SampleResult是类SampleResult的对象,保存当前请求和响应的信息,具体内部方法使用,请看
ResponseCode响应的status code,默认为200
ResponseMessage响应信息,默认为"OK"
IsSuccess请求是否成功,默认为true
Label采样器的标签,即Name字段
FileName文件名,如果Script file有包含外部bsh文件

2.BeanShell PreProcessor

假设现在有一个登录HTTP接口,且这个登录接口对密码做了Base64加密,这个时候我们要测试这个登录接口,就可以使用BeanShell前置处理器 ,先利用脚本将密码做Base64加密,HTTP采样器中再使用密码这个变量的值。

img

Reset bsh.Interpreter before each call(1):和BeanShell Sampler中的2一样,True表示勾选。
内置对象(4):

sampler是类Sampler的对象,表示当前采样器

3.BeanShell PostProcessor

BeanShell后置处理器,可以用于处理响应数据。比如现在有一个接口返回的数据数据是加密的,也可以在后置处理器里先对响应数据做解密。

img

如果我们要认为修改响应数据,那么就可以通过prev这个对象来修改,prev是SampleResult的对象,查看SampleResult类的文档,可以看到一个方法:

byte[] b = "Hello,World".getBytes();
prev.setResponseData(b);

img

4.BeanShell Timer

定时器会让作用域内的每一个采样器都在执行前等待一个固定的时长,如果作用域内有多个定时器,那这多个定时器就会在采样器之前全部执行,所以多个定时器的延迟时长是每个定时器的延时时长的累加。

img

现在,我们想要一个采样器延迟3秒再执行,写入如下代码:

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

从日志文件bin/jmeter.log中可以看到采样器延迟了3秒。

5.BeanShell Assertion

img

可以看到BeanShell断言的内置对象很多,可读/可写的意思是我们可以更改,比如说SampleResult是当前请求响应的数据,说白了,在BeanShell断言里同样可以修改响应数据,和BeanShell后置处理器一样。

Failureboolean,用来设置断言状态,为true,表明断言失败
FailureMessageString,用来设置断言信息
SampleResultSampleResult,具体内部方法,请看
ResponseSampleResult,具体内部方法,请看
ResponseDatabyte[],响应数据
ResponseCodeString,status code的值,比如200,404
ResponseMessageString,响应信息,比如OK
ResponseHeadersString,响应头
RequestHeadersString,请求头
SampleLabelString,采样器的Name
SamplerDataString,就是截图中的内容

现在我们用ResponseCode来判断,等于200时,设置为通过,写入如下代码:

[复制代码](javascript:void(0)😉

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;
     }

[复制代码](javascript:void(0)😉

img

6.BeanShell Listener

img

内置对象:

sampleEventSampleEvent,具体内部方法,请看

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,并先写入如下脚本:

[复制代码](javascript:void(0)😉

public static void test(){
//定义一个变量
String inout;
//获取变量aa所对应的值,赋值给input
input = vars.get("username");
String output = "hello," + input;
vars.put("new_name",output);
}

test()

[复制代码](javascript:void(0)😉

4、添加一个Sampler --> Debug Sampler,命名为after
5、添加一个Listener --> View Results Tree
6、运行,查看结果:

img

img

上面已经实现了修改变量值,现在我想把这段代码提取到一个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中写入如下代码:

[复制代码](javascript:void(0)😉

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

//获取变量aa所对应的值
String str1 = vars.get("username");

//调用java文件中test函数,对于
String str2 = new BeanShellMethod().test(str1);

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

[复制代码](javascript:void(0)😉

运行,从after中可以看到new_name变量被修改了。

img

引用字节码文件

上面我们有了BeanShellMethod.java,可以将其编译为后缀为.class的字节码文件,方式如下:

javac BeanShellMethod.java

img

img

Jmeter提供了addClassPath函数,来引用字节码文件。在BeanShell Sampler中写入如下代码:

[复制代码](javascript:void(0)😉

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

//注意这里导入类,注意也有加;
import BeanShellMethod;

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

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

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

[复制代码](javascript:void(0)😉

运行,从after中可以看到new_name变量被修改了。

img

引用外部jar包

Jmeter引用外部jar包方法:将jar包拷贝到jmeter/lib/ext目录下,这种需要重启Jmeter,才能加载这个jar包;

首先编辑java文件,然后再将.class文件打包成jar包,再将jar包拷贝到对应目录.然后在BeanShell Sampler中写入如下代码:

[复制代码](javascript:void(0)😉

import hellotest.BeanShellMethod;

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

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

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

[复制代码](javascript:void(0)😉

运行,从after中可以看到new_name变量被修改了。

img

六、其它用法(接受参数, log等)

1、在Test Plan中定义如下三个变量:

img

2、Bean Shell可脚本如下:

  • a、bean shell可以接受传入参数,如下图:${name} ${age} ${sex}
  • b、参数可以通过bsh.args[]按顺序提取
  • c、bean shell提供了一个内置变量Parameters,来保存参数的集合

[复制代码](javascript:void(0)😉

//获取参数传递过来的值并存入变量中
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")

[复制代码](javascript:void(0)😉

img

3、运行结果如下图:

img

下图中1输入的这两句设置:

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

img

下图中2输入的这两句设置:

这里需要注意,点击【选项】,勾选log Viewer,然后运行,可以查看运行的日志信息

//输出变量集合
log.info(Parameters);

//输出该元件的name
log.info(Label);

img

结果如下图:

[外链图片转存中…(img-l0phpaQz-1605536557827)]

下图中1输入的这两句设置:

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

[外链图片转存中…(img-Q9FKoOZp-1605536557828)]

下图中2输入的这两句设置:

这里需要注意,点击【选项】,勾选log Viewer,然后运行,可以查看运行的日志信息

//输出变量集合
log.info(Parameters);

//输出该元件的name
log.info(Label);

[外链图片转存中…(img-tmtJwZOs-1605536557829)]

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值