1 概述

1.1 导语

你是否遇到以下场景时,头疼该如何解决?

测试场景复杂,测试入参需多样化;

自动化测试灵活,参数需动态生成;

操作的数据量大,数据不能直接罗列。

Jmeter 的 Beanshell 脚本可以解决以上问题。

1.2 Beanshell 简介

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

Jmeter 支持 Beanshell 脚本,即使用者可通过 Beanshell 脚本对 Jmeter 的基本功能进行扩充,实现更多更复杂的测试场景,满足多样化需求,比如自动化测试或者性能测试。

1.3 Beanshell 类型

Jmeter 中主要有六种 Beanshell:

定时器:Beanshell Timer

前置处理器:Beanshell PreProcessor

采样器:Beanshell Sampler

后置处理器:Beanshell PostProcessor

断言:Beanshell 断言

监听器:Beanshell Listener

2 Beanshell 的常见使用方法

Jmeter 中 Beanshell 常用的使用方法有四种:自定义函数、导入 Jar 包、导入 class 文件、Beanshell 常用内置变量。

2.1 自定义函数

自定义函数,即直接在 Beanshell 中编写 Java 代码,Java 代码可在 IDE 工具中调试通过后再复制进 Jmeter 的 Beanshell 中。

销售订单需要关联物料、客户、组织等基础资料,根据接口定义,可通过各基础数据的编码或者 ID 等进行关联,基础数据的编码通常由前缀加流水号加时间生成,可在 Beanshell 中编写生成流水号以及基础资料编码的 Java 方法,供脚本调用。

如下图,在 Beanshell 脚本中实现生成物料编码的功能。

代码如下:

Random itemRnd = new Random();
     //生成一个n位的随机数字字符串
     public static String getRandom(int len) {         
            String source = "0123456789";
                 Random r = new Random();
                 StringBuilder rs = new StringBuilder();
                 for (int j = 0; j < len; j++) {
                     rs.append(source.charAt(r.nextInt(10)));
                 }
                 return rs.toString();
             }

String  ItemNumbers="前缀"+getRandom(5);

除了随机生成基础资料编码,我们在测试过程中,常常需要对请求参数进行 URl 编码和 URL 解码,进行测试和分析。在 Beanshell 脚本中实现 URL 编码和 URL 解码功能的方法如下。

代码如下:


/**
          * @param  the String needing  decoder
          * @return  the result of decoder
          * @Description 进行url解码
          * @Example:getURLDecoderString("%5B%2240029%22%2C%2240153%22%5D"),result:["40029","40153"]
          */
            public static String URLDecoderString(String strInput) {          
                if (null == strInput) {
                    return "";
                }
                String urldecoder = "";
                try {
                    urldecoder = java.net.URLDecoder.decode(strInput, ENCODE);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                return urldecoder;
            }
            /**
              * @param  the String needing  encoder
              * @return  the result of encoder
              * @Description 进行url编码
              * @Example:getURLEncoderString("[\"40029\",\"40153\"]"),result:%5B%2240029%22%2C%2240153%22%5D
              */
            public static String URLEncoderString(String strInput) { 
                if (null == strInput) {
                    return "";
                }
                String urlencoder = "";
                try {       
                    urlencoder = java.net.URLEncoder.encode(strInput, ENCODE);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                return urlencoder;
            }

2.2 导入 Jar 包

编写代码内容较多时,推荐通过导入 Java 的 Jar 包来实现。

在 Java 的 IDE 工具中(比如 eclipse)写好代码,然后把该类生成 Jar 包(在类上【点击右键】->【Export】->【Jar file】)。

导出的 Jar 包放到 Jmeter 目录 “\apache-Jmeter-2.13\lib\ext” 下,或者将 Jar 包的路径添加到测试计划的 Library 中,脚本通过调用 Jar 包中的方法进行使用。

以苍穹人员表单中身份证字段为例,人员中身份证信息要求唯一。创建大批量的人员,需要很多不同的身份证号,可通过代码生成,但由于生成身份证的代码较长,导入 Jar 包是一种不错的方式。

步骤 1:首先在 Java 的 IDE 中编写生成身份证的类。

步骤 2:导出为 Jar 包。

步骤 3:通过测试计划的 Library 进行关联。

把 Jar 包放到 Jmeter 目录 “\apache-Jmeter-2.13\lib\ext” 下。

步骤 4:在 Beanshell 中导入 JAR 包中的类来进行调用。


2.3 导入 class 文件

语法:source(" Java 文件路径"),其中文件路径可以使用绝对路径,也可以使用相对路径。放入 Jmeter 的 bin 目录下,可直接用文件名;放入其他目录下,需写绝对路径。

此处以生成序列码的方法为例子,调用 Java 文件中的 serialNumber 方法,生成 8 位长度的序列码。

Beanshell 示例:

source("D:\Javafile\serialNumber.Java");--引入外部 Java 文件,编写绝对路径,

或者:

source("serialNumber.Javaw"); --文件位于 “Jmeter bin” 目录下。

步骤 1:将代码放入 Java 文件中—serialNumber.Java。

步骤 2:在 Beanshell 脚本中引用。


步骤 3:在请求参数中引用

通过 vars.put(变量名,变量值),将身份证的值存入 Jmeter 变量中,如 vars.put(“Idcard”,” ID”),在新增人员的 http 请求中通过 ${Idcard}引用。

步骤 4:Beanshell 常用内置变量

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

log:写入信息到 jmeber.log 文件,使用方法:log.info(“提交成功!”);

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

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

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

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

props-(JmeterProperties-class Java.util.Properties):操作 Jmeter 属性,该变量引用了 Jmeter 的配置信息,可以获取 Jmeter 的属性。它的使用方法与 vars 类似,但是只能 put 进去 String 类型的值,而不能是一个对象。对应于 Java.util.Properties,使用方法可参考:props.get("START.HMS");注:START.HMS 为属性名,在文件 Jmeter.properties 中定义 props.put("formId"," im_purinbill "); 新增 formId 的字段,值为 im_purinbill

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

getResponseCode() :获取响应 code。

3 Beanshell 脚本的调试

Beanshell 脚本的调试没有 Java IDE 那么方便,我们可以通过以下方式进行调试。

3.1 查看 Log viewer

Log viewer 会展示 Jmeter 一些常规的报错信息,相当于 eclipse 中的控制台。


3.2 设置 log.info() 埋点

3.3 使用 IDE 工具

在 Java 的 IDE 工具调试成功,再放入 Beanshell,常见的 Java 的 IDE 工具有 eclipse 和 IntelliJ IDEA。

3.4 使用 Jmeter 自带的 Debug Sampler

Jmeter 变量都可以通过 Debug Sampler 跟踪,Debug Sampler 会实时将变量值打印出来。

3.5 其他

在 Jmeter 的 Beanshell 中使用 Map 和 List 不能指定数据类型,包括引用 Java 文件的时候,Java 文件也不能这样使用,Jmeter 会报错。

Map params = new HashMap();

需改成:

Map params = new HashMap();


↙↙↙阅读原文可查看相关链接,并与作者交流