jmeter的beanshell脚本开发

一、Beanshell内置变量介绍

Beanshell有一些默认的内置变量,用户可以通过这些变量与JMeter进行交互,其中主要的变量及其使用方法如下:
log:写入信息到控制台中,帮助调试脚本。log 打印日志,写入信息到jmeber.log文件

vars: 操作jmeter变量,生成/更新/获取当前脚本的jmeter变量

props: 操作jmeter属性,生成/更新/获取当前脚本的jmeter属性,使用方法和vars一样

ctx:获取当前线程上下文,可获取当前线程的请求信息和相应信息(eg:可以获取Http请求和响应的所有数据)

prev:获取当前请求的结果

2.SampleResult 获取SampleResult对象,能通过这个对象获取想要的信息。

3.Response 获取Response对象,能通过这个对象获取响应信息。

4.Failure 查看接口调使用能否成功,假如返回false是成功的,true是失败的。

5.FailureMessage 失败信息,没有设置的时候失败信息是空的,能set这个信息。

6.ResponseData 获取response body类型是byte[]。

7.ResponseCode 返回接口code成功是200。

8.ResponseMessage 获取msg成功是OK。

9.ResponseHeaders 获取接口服务端返回的头部信息。

10.RequestHeaders 获取用户端请求的头部信息。

11.SampleLabel 获取接口请求的名称。

12.SamplerData 获取请求的url和body。

13.ctx 代表上下文信息,能直接用。

14.vars即JMeterVariables,操作jmeter变量,这个变量实际引用了JMeter线程中的局部变量容器(本质上是Map),常用方法:

a) vars.get(String key):从jmeter中获得变量值;

b) vars.put(String key,String value):数据存到jmeter变量中;

15.prev 获取前面的sample返回的信息,常用方法:

a) getResponseDataAsString():获取响应信息。

b) getResponseCode() :获取响应code。

二、Beanshell Sampler 示例

  • vars/props/log

通过Beanshell Sampler,测试人员可以编写一些特定逻辑生成的数据,并且通过vars.get、vars.put 或者props.get、props.put 把相应的变量传递到Jmeter脚本当中。

比如有些程序对身份证有校验,就可以在Beanshell脚本中编写身份证生成的逻辑,通过代码生成满足位数以及省市区编码校验的身份证号,然后把生成的身份证号作为变量保存到vars或者props当中,供后续接口调用。

vars.get(String,String) 可以获取Jmeter中已经生成的变量 vars.put(String,String) 可以创建和更新Jmeter变量 props.get(String,String) 可以获取Jmeter中已经生成的属性 props.put(String,String) 可以创建和更新Jmeter属性 vars和props的区别是前者是变量,只能在同一线程组内传递,后者是属性,可以在整个测试计划中跨线程组传递。 log.info(String) 可以将信息输出到控制台,方便代码调试

三、Beanshell Postprocessor 示例

  • ctx/prev

ctx内置变量可以获取上下文,通常和Beanshell PostProcessor结合起来使用,用于解析请求的结果,具体代码如下所示。在Jmeter的Beanshell脚本编辑器里可以直接引用Jmeter的Jar包,Jmeter Jar包的Api参见官网(http://jmeter.apache.org/api/overview-summary.html

prev等同于ctx.getPreviousResult(),通过prev可以直接获取到响应结果

四、Beanshell编写案例脚本

1、uuid转成32位长度

import java.util.UUID;
String id=UUID.randomUUID().toString().replaceAll("-","");
vars.put("ywzj",id);

2、请求参数字符串拼接

关联参数设置获取所有

int total = ${ldxxbh_matchNr};
log.info("ldxxbh总个数:" + ${ldxxbh_matchNr});
String ldxxbhAll = "";
if(total!=0){//接收返回数据非空时才执行拼装多个ldxxbh
for(int i=1;i<=total;i++){
 String ldxxbhStr = vars.get("ldxxbh_"+i);
 ldxxbhAll = ldxxbhAll + "{\"ldxxbh\":\"" + ldxxbhStr + "\", \"ack\": \"1\"},";
}
}else{
 ldxxbhAll = "{\"ldxxbh\":\"" + "\", \"ack\": \"1\"},";
}
ldxxbhAll = ldxxbhAll.substring(0,ldxxbhAll.length()-1);
//log.info("变量值:"+ldxxbhAll);
vars.put("ldxxbhPar",ldxxbhAll);
//log.info("参数值:" + vars.get("ldxxbhPar"));

3、返回数据写入文本

import java.io.FileWriter; 
import java.io.IOException;
int num=${ywzjid_matchNr};
log.info("ywzjid总个数:" + num);
if(num!=0){//num非空时才执行写入数据
for(int i=1;i<=num;i++){
 String ywzjid = vars.get("ywzjid_"+i);
 String fileName = "ywzjid.txt";
 FileWriter fw = new FileWriter(fileName, true);
 fw.write(ywzjid);
 fw.write("\r\n");
 fw.close();
}
}

4、jmeter引入自己的jar包,beanshell中路径需要写到类名

将jar包放入jmeter\lib下

import com.test.secure.secure.des.DESCoderHelper; 
DESCoderHelper des = new DESCoderHelper();
String key = "12345678";
String paramsSecret = des.encryptNetString(params,key);
vars.put("paramsSecretP",paramsSecret);

5、日志处理

需使用断言中的beanshell断言,若使用的是后置处理器则不正确。

String response = prev.getResponseDataAsString();
String str = "\"Code\":\"000\"";
boolean a = response.contains(str);
if(a==true){
Failure=false;//断言成功
//FailureMessage = "pass:" + response;
//log.info(FailureMessage);
}else{
Failure=true;//断言失败
FailureMessage = "fail:" + vars.get("code");//response
log.info(FailureMessage);
}

字符串包含判断

String response = "";
String Str = "JMeter性能测试2";
response = prev.getResponseDataAsString();//获取当前请求响应结果
if(response == "")
{
 Failure = true;
 FailureMessage = "系统无响应,获取不到响应数据";
 log.info(FailurMessage);
}else if(response.contains(Str)==false){
 Failure = true;
 String msg = "\n系统返回响应结果与预期结果不一致!请排查是性能问题,还是程序代码问题";
 FailureMessage = msg + "\n" + "期望结果:\n" + Str + "\n" + "响应内容:\n"  + response + "\n";
 log.info(FailureMessage); 
}else{
Failure=false;
}

6、时间处理

SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String date = df.format(new Date());
vars.put("date",date);

7、跨线程组变量使用,设置全局变量

应用场景:登录无法支持500并发,但其他场景需要测试500并发时,只需使用一次登录的cookie即可
登录场景单独一个线程组,设置全局变量

${__setProperty(p_session,${access_token},)}

另外线程组使用

${__P(p_session,)}

8、左右边界查找,碰到请求头换行的响应内容获取处理

${__unescape(\n)}

9、线程组和执行时间参数化

${__P(threads5,0)}
${__P(duration,0)}

10、base64位加密和解密函数

base64加密函数

${__base64Encode({"qtId":"cd4a8ed50eca449a82556aae38b6af97"\,"batchId":"cd4a8ed50eca449a82556aae38b6af97"\,"drtk":"502ad80d34b7de6408ba677506ac52ce"},dataBase64Encode)};

dataBase64Encode为存储加密内容的参数名
base64解密函数

${__base64Decode(eyJxdElkIjoiY2Q0YThlZDUwZWNhNDQ5YTgyNTU2YWFlMzhiNmFmOTciLCJiYXRjaElkIjoiY2Q0YThlZDUwZWNhNDQ5YTgyNTU2YWFlMzhiNmFmOTciLCJkcnRrIjoiNTAyYWQ4MGQzNGI3ZGU2NDA4YmE2Nzc1MDZhYzUyY2UifQ==,dataBase64Decode)};

来源: https://i.cnblogs.com/posts/edit;postId=15649080

posted on 2021-12-06 11:16  seamy  阅读(260)  评论(0编辑  收藏  举报