Step1: 什么是BeanShell 
BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法; 
BeanShell是一种松散类型的脚本语言(这点和JS类似); 
BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简的解释器jar文件大小为175k。 
BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法。 
简洁点说就是,java代码怎么写,在这里就可以怎么用。

Step2: Jmeter有哪些Bean Shell 
定时器:  BeanShell Timer 
前置处理器:BeanShell PreProcessor 
采样器:  BeanShell Sampler 
后置处理器:BeanShell PostProcessor 
断言:   BeanShell断言 
监听器:  BeanShell Listener

Step3: BeanShell的使用场景 
场景1:业务单据参数化时要生成一组(多个时间,比如订单日期,发货日期等)未来的时间,运用JMeter提供的时间函数并不能较好的完成。 
场景2:测试Java接口,确又不想继承AbstractJavaSamplerClient 来完成,此时可以用BeanShell Sampler来完成。 
场景3:线程共享变量,我们希望线程之间共享一个变量,可以利用BeanShell来完成。

Step4: BeanShell的使用 
在这个例子中使用的是BeanShell PreProcessor,其它的BeanShell用法类似。 
简单描述一下使用场景: 
调用登录接口时,需要向服务器发送用户名和密码。先看一下简单的接口文档。 

è¿éåå¾çæè¿°

 

密码是MD5加密后的,不能直接提交原始密码,否则会报错。 
提交原始密码后服务器的返回值: 

è¿éåå¾çæè¿°


正确的请求结果应该是: 

è¿éåå¾çæè¿°


那么需要做的工作是,在每次发送请求之前,要将原始密码MD5加密后再请求服务器。 
将密码加密的过程放在BeanShell PreProcessor中完成。因为组件的执行时有顺序的,前置处理器是在Sampler之前执行。 
TestPlan的组件执行是有序的,通过以下顺序执行: 
1. 配置节点 
2. 前置处理器 
3. 定时器 
4. 采样器 
5. 后置处理器 
6. 断言 
7. 监听器 
在intellij idea中创建一个工具类,该类完成MD5加密的功能,并将其打包成工具类jar。

 

package com.test.utils;

/* MD5加密类 */ 
import java.security.MessageDigest;

public class MD5 { 
private final static String[] hexDigits = {“0”, “1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “a”, “b”, “c”, “d”, “e”, “f”};

private static String byteArrayToHexString(byte[] b) { 
    StringBuffer resultSb = new StringBuffer(); 
    for (int i = 0; i < b.length; i++) { 
        resultSb.append(byteToHexString(b[i])); 
    } 
    return resultSb.toString(); 
} 

private static String byteToHexString(byte b) { 
    int n = b; 
    if (n < 0) n = 256 + n; 
    int d1 = n / 16; 
    int d2 = n % 16; 
    return hexDigits[d1] + hexDigits[d2]; 
} 

public static String MD5Encode(String origin) { 
    String resultString = null; 
    try { 
        resultString=new String(origin); 
        MessageDigest md = MessageDigest.getInstance("MD5"); 
        resultString=byteArrayToHexString(md.digest(resultString.getBytes())); 
    } 
    catch (Exception ex) {
        ex.printStackTrace();
    } 
    return resultString; 
}

public static String MD5Encode(String origin, String charsetname) {
    String resultString = null;
    try {
        resultString = new String(origin);
        MessageDigest md = MessageDigest.getInstance("MD5");
        if (charsetname == null || "".equals(charsetname))
            resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
        else
            resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
    } catch (Exception exception) {
    }
    return resultString;
}

}

将该工具类jar包放在把%jmeter%\lib\ext下即可,重新启动Jmeter。 
在前置处理器中添加BeanShell PreProcessor。导入需要的包,编写java代码。 


Bean Shell常用内置变量

JMeter在它的BeanShell中内置了变量,用户可以通过这些变量与JMeter进行交互,其中主要的变量及其使用方法如下:

log:写入信息到jmeber.log文件,使用方法:log.info(“This is log info!”);

ctx:该变量引用了当前线程的上下文,使用方法可参考:org.apache.jmeter.threads.JMeterContext。

vars - (JMeterVariables):操作jmeter变量,这个变量实际引用了JMeter线程中的局部变量容器(本质上是Map),它是测试用例与BeanShell交互的桥梁,常用方法:

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

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

 更多方法可参考:org.apache.jmeter.threads.JMeterVariables

props - (JMeterProperties - class java.util.Properties):操作jmeter属性,该变量引用了JMeter的配置信息,可以获取Jmeter的属性,它的使用方法与vars类似,但是只能put进去String类型的值,而不能是一个对象。对应于java.util.Properties。

 a) props.get(“START.HMS”);  注:START.HMS为属性名,在文件jmeter.properties中定义

 b) props.put(“PROP1”,”1234”);

prev - (SampleResult):获取前面的sample返回的信息,常用方法:

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

 b) getResponseCode() :获取响应code

 更多方法可参考:org.apache.jmeter.samplers.SampleResult

sampler - (Sampler):gives access to the current sampler

vars.put(“md5_password”, encode);就是将加密后的密码放到md5_password这个变量中,如果要调用该变量就使用${md5_passwrod}即可。 


发送请求,看看结果。 

 

 

接着前面的例子,发出请求并收到相应信息。我们要验证一下response中的数据是否正确。要处理请求后的相应数据,可以给Sampler添加一个后置处理器BeanShell PostProcessor。

返回的数据为json格式的。 

{ 
 “authcode”: “a29e486fda3e2415a522f36561ba82de”, 
 “realName”: “个人测试账号”, 
 “errno”: 0 
} 


Step1: 
我们检查errno这个字段的值是否为0,需要解析json数据。 
这次换一种解决思路。不用将工具类打成jar包,而是把编写工具类使用的jar放到一个目录下,将该目录添加到classpath中。

è¿éåå¾çæè¿°

Step2: 
然后就可以向写普通的java代码一样,完成json数据的解析过程。将获取到的值再放到jmeter变量中供其它处调用。 

è¿éåå¾çæè¿°

其中 prev.getResponseDataAsString()是获取前一个请求的响应数据。 
Step3: 
添加BeanShell断言 
è¿éåå¾çæè¿°

在断言中,可以将jmeter的变量到参数中。 

è¿éåå¾çæè¿°

使用的方法是bsh.args[0]。第一个参数是bsh.args[0], 如果还有其它参数,要依次使用角标来取出。 
参数之间用空格间隔开。

è¿éåå¾çæè¿°

另外: 
在Jmeter中还有一种特殊的用法,就是使用source将外部的java文件直接导入。 
读取一个本地文件,要将文件中的json数据解析,得到用户的id。 
这里写图片描述

这里写图片描述

最后添加一个BeanShell的断言 

这里写图片描述

还有就是我们可以指定一些常用的值,来帮助测试。 

这里写图片描述

这里写图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐