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在此不做详细介绍,使用前面几个举例子
log:用来记录日志文件,写入到jmeber.log文件,参考 org.apache.log.Logger
官网给出是slf4j.Logger 我查检查了jar包,没有发现什么异常,如果有哪位发现是什么问题,请指正
ctx:(JmeterContext)通过它来访问context,参考:org.apache.jmeter.threads.JMeterContext
在测试计划中创建一个前置处理器(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
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());
相对preProcessor,内置变量去掉了sampler,增加data,在此只说data,其他参考preProcessor
data:保存response内容,是一个byte[],保存的是取样器的结果,一般要对结果做特殊处理的时候使用,比如要取出来后做二次加工或者将部分内容定制化输出等……
新建BeanShell PostProcessor
System.out.println(ctx.getCurrentSampler().getName()+" ======Start======");
for(int i=0;i
System.out.print(((char)data[i]).toString());
}
System.out.println(ctx.getCurrentSampler().getName()+" ======End======");
函数里面写入响应的表达式,可以引用BeanShell中的变量等,可以直接使用的变量比较多 参考BeanShell Sampler
preProcessor、postProcessor、BeanShell函数与普通取样器传参
//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
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 "测试而已,在此可有可无";
System.out.println(ctx.getCurrentSampler().getName()+" ======Start======");
for(int i=0;i
System.out.print(((char)data[i]).toString());
}
System.out.println(ctx.getCurrentSampler().getName()+" ======End======");
return "不啰嗦,直接返回!!"
beanshell中可以写更复杂的例子如定义方法,引入外部类等
引入外部类几种方式
孤立的类
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);
}
}
在之前的测试计划上做如下修改:
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
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 "测试而已,在此可有可无";