• jmeter的beanshell脚本开发


    ##一、Beanshell内置变量介绍
    Beanshell有一些默认的内置变量,用户可以通过这些变量与JMeter进行交互,其中主要的变量及其使用方法如下:
    •  log:写入信息到控制台中,帮助调试脚本。log 打印日志,写入信息到jmeber.log文件

    •  vars:  操作jmeter变量,生成/更新/获取当前脚本的jmeter变量

    •  props:  操作jmeter属性,生成/更新/获取当前脚本的jmeter属性,使用方法和vars一样

    •  ctx:获取当前线程上下文,可获取当前线程的请求信息和相应信息(eg:可以获取Http请求和响应的所有数据)

    •  prev:获取当前请求的结果

    2.SampleResult 获取SampleResult对象,能通过这个对象获取想要的信息。

    3.Response 获取Response对象,能通过这个对象获取响应信息。

    4.Failure 查看接口调使用能否成功,假如返回false是成功的,true是失败的。

    5.FailureMessage 失败信息,没有设置的时候失败信息是空的,能set这个信息。

    6.ResponseData 获取response body类型是byte[]。

    7.ResponseCode 返回接口code成功是200。

    8.ResponseMessage 获取msg成功是OK。

    9.ResponseHeaders 获取接口服务端返回的头部信息。

    10.RequestHeaders 获取用户端请求的头部信息。

    11.SampleLabel 获取接口请求的名称。

    12.SamplerData 获取请求的url和body。

    13.ctx 代表上下文信息,能直接用。

    14.vars即JMeterVariables,操作jmeter变量,这个变量实际引用了JMeter线程中的局部变量容器(本质上是Map),常用方法:

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

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

    15.prev 获取前面的sample返回的信息,常用方法:

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

    b) getResponseCode() :获取响应code。

     

    ##二、Beanshell Sampler 示例 

    - vars/props/log


    通过Beanshell Sampler,测试人员可以编写一些特定逻辑生成的数据,并且通过vars.getvars.put 或者props.getprops.put 把相应的变量传递到Jmeter脚本当中。

    比如有些程序对身份证有校验,就可以在Beanshell脚本中编写身份证生成的逻辑,通过代码生成满足位数以及省市区编码校验的身份证号,然后把生成的身份证号作为变量保存到vars或者props当中,供后续接口调用。

     vars.get(String,String) 可以获取Jmeter中已经生成的变量 vars.put(String,String) 可以创建和更新Jmeter变量 props.get(String,String) 可以获取Jmeter中已经生成的属性 props.put(String,String) 可以创建和更新Jmeter属性 varsprops的区别是前者是变量,只能在同一线程组内传递,后者是属性,可以在整个测试计划中跨线程组传递。 log.info(String) 可以将信息输出到控制台,方便代码调试 

    ##三、Beanshell Postprocessor 示例

    - ctx/prev

    ctx内置变量可以获取上下文通常和Beanshell PostProcessor结合起来使用,用于解析请求的结果,具体代码如下所示。在JmeterBeanshell脚本编辑器里可以直接引用JmeterJar包,Jmeter Jar包的Api参见官网(http://jmeter.apache.org/api/overview-summary.html  

    prev等同于ctx.getPreviousResult(),通过prev可以直接获取到响应结果
    ##四、Beanshell编写案例脚本
    ###1、uuid转成32位长度
    ```
    import java.util.UUID;
    String id=UUID.randomUUID().toString().replaceAll("-","");
    vars.put("ywzj",id);
    ```
    ###2、请求参数字符串拼接
    关联参数设置获取所有
    ```
    int total = ${ldxxbh_matchNr};
    log.info("ldxxbh总个数:" + ${ldxxbh_matchNr});
    String ldxxbhAll = "";
    if(total!=0){//接收返回数据非空时才执行拼装多个ldxxbh
    for(int i=1;i<=total;i++){
     String ldxxbhStr = vars.get("ldxxbh_"+i);
     ldxxbhAll = ldxxbhAll + "{\"ldxxbh\":\"" + ldxxbhStr + "\", \"ack\": \"1\"},";
    }
    }else{
     ldxxbhAll = "{\"ldxxbh\":\"" + "\", \"ack\": \"1\"},";
    }
    ldxxbhAll = ldxxbhAll.substring(0,ldxxbhAll.length()-1);
    //log.info("变量值:"+ldxxbhAll);
    vars.put("ldxxbhPar",ldxxbhAll);
    //log.info("参数值:" + vars.get("ldxxbhPar"));
    ```
    ###3、返回数据写入文本
    ```
    import java.io.FileWriter; 
    import java.io.IOException;
    int num=${ywzjid_matchNr};
    log.info("ywzjid总个数:" + num);
    if(num!=0){//num非空时才执行写入数据
    for(int i=1;i<=num;i++){
     String ywzjid = vars.get("ywzjid_"+i);
     String fileName = "ywzjid.txt";
     FileWriter fw = new FileWriter(fileName, true);
     fw.write(ywzjid);
     fw.write("\r\n");
     fw.close();
    }
    }
    ```
    ###4、jmeter引入自己的jar包,beanshell中路径需要写到类名
    ```
    import com.test.secure.secure.des.DESCoderHelper;
    DESCoderHelper des = new DESCoderHelper();
    String key = "12345678";
    String paramsSecret = des.encryptNetString(params,key);
    vars.put("paramsSecretP",paramsSecret);
    ```
    ###5、日志处理
    需使用断言中的beanshell断言,若使用的是后置处理器则不正确。
    ```
    String response = prev.getResponseDataAsString();
    String str = "\"Code\":\"000\"";
    boolean a = response.contains(str);
    if(a==true){
    Failure=false;//断言成功
    //FailureMessage = "pass:" + response;
    //log.info(FailureMessage);
    }else{
    Failure=true;//断言失败
    FailureMessage = "fail:" + vars.get("code");//response
    log.info(FailureMessage);
    }
    ```
    字符串包含判断
    ```
    String response = "";
    String Str = "JMeter性能测试2";
    response = prev.getResponseDataAsString();//获取当前请求响应结果
    if(response == "")
    {
     Failure = true;
     FailureMessage = "系统无响应,获取不到响应数据";
     log.info(FailurMessage);
    }else if(response.contains(Str)==false){
     Failure = true;
     String msg = "\n系统返回响应结果与预期结果不一致!请排查是性能问题,还是程序代码问题";
     FailureMessage = msg + "\n" + "期望结果:\n" + Str + "\n" + "响应内容:\n"  + response + "\n";
     log.info(FailureMessage); 
    }else{
    Failure=false;
    }
    ```
     
    ###6、时间处理
    ```
    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
    String date = df.format(new Date());
    vars.put("date",date);
    ```
    ###7、跨线程组变量使用,设置全局变量
    应用场景:登录无法支持500并发,但其他场景需要测试500并发时,只需使用一次登录的cookie即可
    登录场景单独一个线程组,设置全局变量
    ```
    ${__setProperty(p_session,${access_token},)}
    ```
    另外线程组使用
    ```
    ${__P(p_session,)}
    ```
    ###8、左右边界查找,碰到请求头换行的响应内容获取处理
    ```
    ${__unescape(\n)}
    ```
    ###9、线程组和执行时间参数化
    ```
    ${__P(threads5,0)}
    ${__P(duration,0)}
    ```
    ###10、base64位加密和解密函数
    base64加密函数
    ```
    ${__base64Encode({"qtId":"cd4a8ed50eca449a82556aae38b6af97"\,"batchId":"cd4a8ed50eca449a82556aae38b6af97"\,"drtk":"502ad80d34b7de6408ba677506ac52ce"},dataBase64Encode)};
    ```
    dataBase64Encode为存储加密内容的参数名
    base64解密函数
    ```
    ${__base64Decode(eyJxdElkIjoiY2Q0YThlZDUwZWNhNDQ5YTgyNTU2YWFlMzhiNmFmOTciLCJiYXRjaElkIjoiY2Q0YThlZDUwZWNhNDQ5YTgyNTU2YWFlMzhiNmFmOTciLCJkcnRrIjoiNTAyYWQ4MGQzNGI3ZGU2NDA4YmE2Nzc1MDZhYzUyY2UifQ==,dataBase64Decode)};
    ```
  • 相关阅读:
    viewport
    Flex 布局教程
    鼠标放上去盒子向上滑动
    鼠标放图片上,原图上划上去一个透明图片
    类加载过程
    JVM入门
    redis简介和安装
    JMH和Disruport
    线程池
    JUC
  • 原文地址:https://www.cnblogs.com/seamy/p/15649080.html
Copyright © 2020-2023  润新知