侧边栏壁纸
博主头像
一朵云的博客博主等级

拥抱生活,向阳而生。

  • 累计撰写 68 篇文章
  • 累计创建 25 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

JMeter -- BeanShell使用

一朵云
2022-02-17 / 0 评论 / 1 点赞 / 8822 阅读 / 9263 字

Bean Shell 介绍:

  • BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;

  • BeanShell是一种松散类型的脚本语言(这点和JS类似);

  • BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简的解释器jar文件大小为175k。

  • BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法。

  官网地址:http://www.BeanShell.org/

Jmeter 使用到 BeanShell 的组件:

  • 定时器:   BeanShell Timer

  • 前置处理器: BeanShell PreProcessor

  • 采样器:   BeanShell Sampler

  • 后置处理器: BeanShell PostProcessor

  • 断言:    BeanShell断言

  • 监听器:   BeanShell Listener

Beanshell的内置变量和方法

段落引用Beanshell有一些默认的内置变量和方法,用户可以通过这些变量与JMeter进行交互,例如:
print:非GUI模式下打印信息(输出信息到stdout,标准输出控制台)。
log:输出信息到日志(文件)

日志打印级别:

  • log.debu(“调试信息”)

  • log.info(“响应状态码” + ResponseCode)

  • log.warn(“警告信息”)

  • log.error(“出错信息”)


获取响应变量:

  • ResponseCode:响应状态码(String类型)。

  • ResponseHeaders:响应头(String类型)。


获取请求结果:

  • prev:获取当前请求结果

  • prev.getResponseDataAsString():获取响应体数据(String类型)。

  • prev.getResponseCode():获取状态码(同ResponseCode,String类型)。


jmeter变量(线程内生效):

  • vars:操作JMeter变量

  • String var1 = vars.get(“变量名”):获取变量的值(假设为String类型)。

  • vars.put(“变量名”, 变量值):设置变量值。

  • jmeter内置函数 ${变量名}


jmeter属性(可跨线程):

  • props:操作JMeter属性

  • props.get(String,String) 可以获取JMeter中已经生成的属性。

  • props.put(String,String)可以创建和更新JMeter属性。

  • jmeter内置函数 ${__property(变量名)} 或 ${__P(变量名)}


线程上下文:

  • ctx:获取当前线程上下文数据(可获取所有信息)

  • ctx.getVariables(“变量名”):获取变量值(同vars.get())。

  • ctx.setVariables(“变量名”, “变量值”):设置变量(同vars.put())。

  • ctx.getProperties(“属性名”):获取属性值(同props.get())。

  • ctx.setProperties(“属性名”,“属性值”):设置属性(同props.put())。

  • ctx.getPreviousResult():获取当前请求结果同(prev)。

  • ctx.getCurrentSampler():获取当前采样器。

  • ctx.getPreviousSampler():获取前一采样器。

  • ctx.getThreadNum():获取线程数。

  • ctx.getThreadGroup():获取线程组。

  • ctx. getThread():获取当前线程。

  • ctx.getEngine():获取引擎。

  • ctx.isSamplingStarted():判断采样器是否启动。

  • ctx.isRecording():判断是否开启录制。

  • ctx.getSamplerContext():获取采样器山下文数据。

示例演示:

  需模拟下图中的get请求,其中sign是通过代码生成的,如若每次请求前,都复制入参去编译器生成将十分麻烦,此时可考虑使用beanshell。

image.png

编译器中调试代码:

image.png

将代码复制进BeanShell取样器中调试:

import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.security.*;
import java.math.BigInteger;

public class MySign {

    //获取签名字符串
    public static String getSign(String appId,String channelId,String deviceId,String dateStart,String dateEnd,String periodId,String signKey){

        HashMap map = new HashMap();
        map.put("appId",appId);
        map.put("channelId",channelId);
        map.put("deviceId",deviceId);
        map.put("dateStart",dateStart);
        map.put("dateEnd",dateEnd);
        map.put("periodId",periodId);

        String signStr = genSign(map, signKey);

        return signStr;
    }

    // md5算法
    public static String md5(String plainText) {
        byte[] secretBytes = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes("utf-8"));
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            throw new RuntimeException("no such algorithm!");
        }

        String md5code = new BigInteger(1, secretBytes).toString(16);
        int length = md5code.length();
        for (int i = 0; i < 32 - length; i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    // 签名算法
    public static String genSign(HashMap<String, String> params, String signKey) {
        String result = "";
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(params.entrySet());
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造签名键值对的格式
            for (Map.Entry<String, String> item : infoIds) {
                if (item.getKey() != null || item.getKey() != "") {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (result == "") {
                        result += key + "=" + URLEncoder.encode(val, "UTF-8");
                    } else {
                        result += "&" + key + "=" + URLEncoder.encode(val, "UTF-8");
                    }
                }
            }

            // System.out.println(result);
        } catch (Exception e) {
            throw new RuntimeException("error");
        }
        // System.out.println(signKey+result);
        return md5(signKey + result);
    }

}

String sign = new MySign().getSign("${appId}","${channelId}","${deviceId}","${dateStart}","${dateEnd}","${periodId}","signKey");
vars.put("Sign",sign);

调试结果:

BeanShell不支持java泛型,编译不通过。

image.png

不支持java泛型的解决方案:

1、优化代码,不使用泛型。(复杂代码不推荐)

2、代码封装成jar包,在通过BeanShell引入使用。(简单粗暴,推荐)

①、从idea 将代码打包jar包:

image.png

image.png

image.png

image.png

image.png

image.png

②、测试计划中引入jar包依赖:

image.png

③、BeanShell 中导入调用类方法:

image.png

④、测试是否调用成功:

image.png

image.png

image.png

完成。

1

评论区