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=0;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
    //这里是获取前一个取样器的结果,若没有,会报空指针,最简单的办法线程组至少运行2次,第二次即可获取
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=0;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=0;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
    //这里是获取前一个取样器的结果,若没有,会报空指针,最简单的办法线程组至少运行2次,第二次即可获取
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=0;i<data.length;i++){
    System.out.print(((char)data[i]).toString());   
}
System.out.println(ctx.getCurrentSampler().getName()+" ======End======");
  • 新建BeanShell Sampler
    在该案例中直接返回,不写任何内容
return "不啰嗦,直接返回!!"
  • 新建线程组并新建http请求 设置运行两次
    线程组
    参数kw的值是BeanShell表达式,取值为在preProcessor中放入的参数testObj
    参数test的值是普通表达式,取值为在preProcessor中放入的参数test
    运行结果

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=0;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
    //这里是获取前一个取样器的结果,若没有,会报空指针,最简单的办法线程组至少运行2次,第二次即可获取
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(1,2);
JmeterBeanShellSourceTest jmeterBeanShellSourceTest = new JmeterBeanShellSourceTest();
jmeterBeanShellSourceTest.sayhello("tom");
log.info("source result="+String.valueOf(sourceresult));

JmeterBeanShellTest jmeterBeanShellTest = new JmeterBeanShellTest();
int result=jmeterBeanShellTest.add(1,2);
jmeterBeanShellTest.sayhello("tom");
log.info("result="+String.valueOf(result));

return "测试而已,在此可有可无";

猜你喜欢

转载自blog.csdn.net/yue530tomtom/article/details/80855524