遇一山,过一山,处处有风景;只要勇敢向前,一路尽是繁花盛开。 | (点击查看→)【测试干货】python/java自动化、持续集成、性能、测开、简历、笔试面试等

玩转jmeter:beanshell必备技能

beanshell是什么

BeanShell是一个小型嵌入式Java源代码解释器,能够动态地执行java代码。

下载及运行

下载地址:https://beanshell.github.io/download.html

 

java -jar直接运行

  

测试

 

其它方式启动:先把jar包加入到环境变量

 

界面UI方式 :java bsh.Console

 

  

命令行方式 :java bsh.Interpreter

 

运行脚本文件:java bsh.Interpreter filename [args]

第一个例子

第二个例子

运行结果

如果jar包没加到环境变量,可以这样运行:java -classpath %CLASSPATH%;bsh-2.0b4.jar bsh.Interpreter test.txt

 

jmeter中beanshell 

而我们的jmeter中,已经自带了jar包,下面介绍jmeter中如何使用beanshell

 

添加变量

下面import的类,在jmeter的lib下:commons-codec-1.11.jar

引用变量

发送请求,可以看到密码加密了

自定义函数

上面也可以封装为函数

下面方法返回类型为void

import org.apache.commons.codec.digest.DigestUtils;

public static void fun(){
    String password_md5 = DigestUtils.md5Hex("123456");
    vars.put("password_md5", password_md5);
}
 
fun(); 

 

下面方法返回类型为String 

import org.apache.commons.codec.digest.DigestUtils;

public static String fun(){
    String password_md5 = DigestUtils.md5Hex("123456");
    print(password_md5);  // 在命令行窗口打印结果
    return password_md5;    
}
 
String password_md5 = fun();
vars.put("password_md5", password_md5);

  

也可以写成这样(方法不写返回类型)

import org.apache.commons.codec.digest.DigestUtils;

fun(){
    String password_md5 = DigestUtils.md5Hex("123456");
    print(password_md5);  // 在命令行窗口打印结果
    return password_md5;    
}
 
String password_md5 = fun();
vars.put("password_md5", password_md5);

  

 

甚至写成这样(定义的变量也没类型)

import org.apache.commons.codec.digest.DigestUtils;

fun(){
    String password_md5_res = DigestUtils.md5Hex("123456");
    print(password_md5_res);  // 在命令行窗口打印结果
    return password_md5_res;    
}
 
password_md5 = fun();
vars.put("password_md5", password_md5);

 

但是还是推荐按照java的方式写,严格定义。 

引用java文件、class文件、jar文件

详见微信公众号:全栈测试笔记

 

https://www.cnblogs.com/uncleyong/p/9429752.html

常用内置变量

JMeter在它的BeanShell中内置了变量,用户可以通过这些变量与JMeter进行交互。

log

vars

prev

Failure

FailureMessage

具体用法请百度,本篇的示例中也有使用到。

beanshell组件(beanshell取样器、beanshell前置处理器、beanshell断言)

Jmeter中包括多种BeanShell,用法差不多,只是作用的地方不同。
定时器:  BeanShell Timer
前置处理器:BeanShell PreProcessor,提前处理请求参数,如:加密解密等
采样器:  BeanShell Sampler
后置处理器:BeanShell PostProcessor,在请求后对返回结果进行处理
断言:   BeanShell断言,验证返回结果的正确性
监听器:  BeanShell Listener

下面举例几个常用的。

beanshell取样器

引用变量

发送请求,可以看到密码加密了

beanshell前置处理器

 

beanshell断言

断言--beanshell断言

 

 

样例一

补充:

public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler {}

JSON.parseObject(res)和JSONObject.parseObject(res)都是调用的JSON类的parseObject方法,JSONObject继承了类JSON

    public static JSONObject parseObject(String text) {
        Object obj = parse(text);
        if (obj instanceof JSONObject) {
            return (JSONObject)obj;
        } else {
            try {
                return (JSONObject)toJSON(obj);
            } catch (RuntimeException var3) {
                throw new JSONException("can not cast to JSONObject.", var3);
            }
        }
    }

  

最简单的案例

{"code":"0","msg":"success"}

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

String res = prev.getResponseDataAsString();
String code = JSON.parseObject(res).getString("code");
log.info(code);
String exp_result = "1";
if (!exp_result.equals(code)) {
    Failure = true;
    FailureMessage = "code与实际值不一致,期望值" + exp_result + ", 实际值" + code;
}
else{
	System.out.println("pass");
}

 

如果字符串唯一,最好就用简单的文本断言

如果非唯一,得用bs断言,例如:

{"code":"0","msg":"success","data":{"code":"0","msg":"成功"}}

断言data里面的code

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
 
String res = prev.getResponseDataAsString();
String code = JSON.parseObject(res).getJSONObject("data").getString("code");
log.info(code);
String exp_result = "1";
if (!exp_result.equals(code)) {
    Failure = true;
    FailureMessage = "code与实际值不一致,期望值" + exp_result + ", 实际值" + code;
}
else{
    System.out.println("pass");
}

 

布尔值字段

{"code":"0","msg":"success","status":"false"}

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
 
String res = prev.getResponseDataAsString();
String status = JSON.parseObject(res).getString("status");
String exp_result = "true";
if (!exp_result.equals(status)) {
    Failure = true;
    FailureMessage = "status与实际值不一致,期望值" + exp_result + ", 实际值" + status;
}
else{
    System.out.println("pass");
}

  

 

{"code":"0","msg":"success","status":false}

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
 
String res = prev.getResponseDataAsString();
//Boolean status = JSON.parseObject(res).getBoolean("status");
 Boolean status = JSON.parseObject(res).getBooleanValue("status");
if (!status) {
    Failure = true;
    FailureMessage = "status实际值是" + status;
}
else{
    System.out.println("pass");
}

  

 

样例二

pom依赖

    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.49</version>
        </dependency>
    </dependencies> 

代码及打的jar包

把jar包复制到jmeter的lib下ext中,重启jmeter

添加用户定义变量 

请求

beanshell前置处理器,加密密码

 

beanshell断言,直接看最后if即可

另外:

获取对象类型:obj.getClass().toString();
Integer.valueOf返回的是Integer对象,Integer.parseInt返回的是int

完整脚本

import com.uncleyong.JsonToJSONObject;
import com.alibaba.fastjson.JSONObject;   // 不能少,下面定义了JSONObject类型

print("===========开始执行==========");
String exp_result = vars.get("exp_result");
print("exp_result= " + exp_result);
print("exp_result的类型:" + exp_result.getClass().toString());  // exp_result的类型:class java.lang.String
//Integer.valueOf返回的是Integer对象,Integer.parseInt返回的是int
Integer exp_result2 = Integer.valueOf(exp_result);
print("exp_result2的类型:" + exp_result2.getClass().toString());  // exp_result2的类型:class java.lang.Integer

String jsonString = prev.getResponseDataAsString();
print("获取到的返回结果:" + jsonString);
print("返回结果的类型:" + jsonString.getClass().toString());  // 返回结果的类型:class java.lang.String

JSONObject responseJson = new JsonToJSONObject().JSONObjectUtil(jsonString);
print("转换后的返回结果:" + responseJson);
print("转换后的返回结果类型:" + responseJson.getClass());  // 转换后的返回结果类型:class com.alibaba.fastjson.JSONObject

String code = responseJson.getString("code");
print("code = " + code);
print("code的类型:" + code.getClass());  // code的类型:class java.lang.String
Integer code2 = responseJson.getInteger("code");
print("code2 = " + code2);
print("code2的类型:" + code2.getClass());  // code2的类型:class java.lang.Integer

//if (code.equals(exp_result)==false) {
if (code2 != exp_result3) {
    print("--------进入if语句--------");
    Failure = true;
    FailureMessage = "code与实际值不一致,期望值" + exp_result + ", 实际值" + code;
}
print("===========结束执行==========");

运行结果

 

 

 

手把手实践

关联:https://www.cnblogs.com/uncleyong/p/14330102.html

《jmeter对接口测试入参进行MD5加密的5种方式》,详见微信公众号:全栈测试笔记

https://www.cnblogs.com/uncleyong/protected/p/9429752.html

 

《性能测试:jmeter中通过beanshell把关联转变成参数化》

https://www.cnblogs.com/uncleyong/p/10986466.html

 

posted @ 2019-05-05 18:39  全栈测试笔记  阅读(6366)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end