Jmeter - 从入门到放弃

文章目录

  • 1 常用测试原件
    • 1.1 环境变量
      • 1.1.1 用户参数
      • 1.1.2 用户定义的变量
      • 1.1.3 jmeter.properties 文件中的变量
    • 1.2 如果(if)控制器
    • 1.3 While 控制器
    • 1.4 循环控制器
    • 1.5 Jmeter 操作数据库
  • 2 Http 接口
    • 2.1 HTTP请求默认值
    • 2.2 Http 请求
    • 2.3 Http 请求 WebService 接口
    • 2.4 Test Fragment
  • 3 Dubbo 接口
    • 3.1 Jmeter 原生插件调用 dubbo 接口
    • 3.2 Jmeter 自定义插件调用 dubbo 接口
  • 4 BeanShell 断言及前后置处理
    • 4.1 BeanShell 断言
      • 4.1.1 基础断言:断言接口是否调用成功
      • 4.1.2 断言字段是否为空
      • 4.1.3 断言数组不为空
      • 4.1.4 断言多个字段不为空
    • 4.2 设置环境变量
    • 4.3 设置全局变量
    • 4.4 打印日志
  • 5 函数助手
    • 5.1 常用函数
      • 5.1.1 获取当前系统时间:__time
      • 5.1.2 生成UUID :__UUID
    • 5.2 自定义函数助手
      • 5.2.1 配置 Jmeter 依赖文件
      • 5.2.2 函数实现
  • 6 Jmeter 自定义插件
    • 6.1 Jmeter 执行 shell 命令
    • 6.2 Jmeter 发送 kafka 消息
  • 引用

1 常用测试原件

1.1 环境变量

1.1.1 用户参数

用户参数:所设置的变量只要在所属线程组才有效
在这里插入图片描述

1.1.2 用户定义的变量

用户定义的变量:所设变量对所有线程组都有效
Jmeter - 从入门到放弃_第1张图片

1.1.3 jmeter.properties 文件中的变量

jmeter.properties 文件中的变量通过函数助手 __P 读取
Jmeter - 从入门到放弃_第2张图片
Jmeter - 从入门到放弃_第3张图片

1.2 如果(if)控制器

Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。

布尔值为 true,进入 If 控制器;
例如: userType 等于 10,则执行 if 控制器下的测试原件

${__groovy("10".equals("${userType}"))}

Jmeter - 从入门到放弃_第4张图片

1.3 While 控制器

While 控制器,布尔值为 true 时进入循环;
While 控制器,布尔值为 false 时不进入循环。
Jmeter - 从入门到放弃_第5张图片
例如:判断 i > 4,则跳出 while 控制器

${__groovy(${i}<=4)}

Jmeter - 从入门到放弃_第6张图片

1.4 循环控制器

Jmeter - 从入门到放弃_第7张图片

1.5 Jmeter 操作数据库

(1)配置 Oracle JDBC Connection Configuration
Jmeter - 从入门到放弃_第8张图片
Jmeter - 从入门到放弃_第9张图片
(2)Jmeter 查询 Oracle 数据库
Jmeter - 从入门到放弃_第10张图片
(3)断言查询结果
Jmeter - 从入门到放弃_第11张图片

if(${SUB_TELCOM_NAME_#} > 0) {	// SUB_TELCOM_NAME_# 表示查询出的个数 
	Failure = false;
} else{
	Failure = true;
 	FailureMessage = "Oracle_installmix 未查询出 SUB_TELCOM_NAME 的值";
}

(4)Jmeter 更新 Oracle 数据库
Jmeter - 从入门到放弃_第12张图片
(5)断言更新结果
Jmeter - 从入门到放弃_第13张图片

String returnData = prev.getResponseDataAsString();	// 获取返回信息
int i = Integer.parseInt(returnData.substring(0,1));	// 提取更新条数
if(i>0){	
	Failure = false;
} else {
	Failure = true;
 	FailureMessage = "Oracle_KHTX 更新条数为0,调用cif造号失败";
}

2 Http 接口

2.1 HTTP请求默认值

对于接口自动化来说,维护是重点,当有多套测试环境,或者 服务器 IP、端口出现变动,都会影响自动化脚本,此时若不通过 HTTP请求默认值统一管理,维护特别困难,
Jmeter - 从入门到放弃_第14张图片

2.2 Http 请求

Jmeter - 从入门到放弃_第15张图片
由于我司http请求的接口入参都做了加密,通过fiddler抓取加密入参,通过自定义的函数助手__cfbossDecryp解密,处理好入参后,再通过__cfbossEncrypt加密
Jmeter - 从入门到放弃_第16张图片
Jmeter - 从入门到放弃_第17张图片
Jmeter - 从入门到放弃_第18张图片
Jmeter - 从入门到放弃_第19张图片

2.3 Http 请求 WebService 接口

Jmeter - 从入门到放弃_第20张图片

2.4 Test Fragment

Test Fragment 的主要作用是模块化, 和模块控制器配合使用;
例如:后台管理系统的接口,需要登录接口生成的 cookie,那写多个不相关流程的时候,需要每个流程都加一个登录接口吗?
之前测试的时候碰到这样的问题,由于安全问题,修改了登录接口的加密方式,而由于自动化多个流程都涉及了登录接口,从而需要一个个去维护这些接口;
因此对于某些通用性的接口,可以通过 Test Fragment 封装起来,其余线程去调用即可。
Jmeter - 从入门到放弃_第21张图片
Jmeter - 从入门到放弃_第22张图片
Jmeter - 从入门到放弃_第23张图片
此外若不同的合作方流程相同,也可以将各个流程通过 Test Fragment 封装成对应的模块,模块中再针对合作方做判断,就不需要去维护多个线程内的脚本,只需要维护 Test Fragment 中各个模块即可。
Jmeter - 从入门到放弃_第24张图片

3 Dubbo 接口

3.1 Jmeter 原生插件调用 dubbo 接口

3.1.1 Dubbo Sample 界面介绍
在这里插入图片描述
在这里插入图片描述
3.1.2 定位 Interface 及 paramType
Jmeter - 从入门到放弃_第25张图片
(1)telnet ip 端口号:连接服务
Jmeter - 从入门到放弃_第26张图片
(2)ls 命令:显示所有服务类的路径,找到需要的服务类,填写在interface
Jmeter - 从入门到放弃_第27张图片
(3)ls -l 服务类:查询出方法名及 paramType
在这里插入图片描述
Jmeter - 从入门到放弃_第28张图片
(4)判断 paramValue 是否包含泛型,若不包含泛型可直接填写json入参

{
	"areaCode": "${areaCode}",
	"businessTypes": "${businessType}",
	"cityCode": "${cityCode}",
	"saleNo": "${inviteCode}",
	"subTel": "${subTel}",
	"switchType": ["switchType","switchType","switchType"],
	"traceLogId": "${__UUID}"
}

Jmeter - 从入门到放弃_第29张图片
(5)判断入参包含泛型:若入参包含“T”,则是泛型
Jmeter - 从入门到放弃_第30张图片
(6)对于包含泛型的入参,通过反编译工具,查询paramType,当然上面第(3)步也可以查询出 paramType
Jmeter - 从入门到放弃_第31张图片
(7)定位 paramValue 中的 class
Jmeter - 从入门到放弃_第32张图片

8 定位 paramValue
Jmeter - 从入门到放弃_第33张图片

{
	"params": {
		"class": "com.bestpay.cf.instalmentmix.api.facade.order.dto.QueryOrderStatusDTO",
		"orderNo": "${orderNo}",
		"phone": "${productNo}"
	},
	"traceLogId": "${__UUID}"
}

Jmeter - 从入门到放弃_第34张图片

3.2 Jmeter 自定义插件调用 dubbo 接口

3.2.1 将接口所在 Jar 包放入 lib 目录中
(1)IDEA 新建一个 maven 工程
(2)maven 设置 setting file 以及 仓库地址
Jmeter - 从入门到放弃_第35张图片
(3)找开发 或在接口文档中 确认pom.xml文件中 maven 的依赖及版本号Jmeter - 从入门到放弃_第36张图片
(4)将 maven 坐标放入 pom.xml 文件中,并下载
Jmeter - 从入门到放弃_第37张图片
(5)jar 包路径为 第 2 步设置的仓库地址,找到jar包后放入 /jmeter/lib 目录下
Jmeter - 从入门到放弃_第38张图片
(7)确认 interface 的两种方法
1.接口文档或找开发人员确认服务类的类名,若 import class 成功,则确认 interface
Jmeter - 从入门到放弃_第39张图片
2.抓包工具或前端控制台确认客户端前置调用的方法
第一步确认分支
Jmeter - 从入门到放弃_第40张图片
第二步在该分支查询 .客户端前置调用的方法,从而确认 该方法调用的核心接口
Jmeter - 从入门到放弃_第41张图片
(8)配置 dubbo-consumer.xml,并放入 /jmeter/dubboxml目录中
Jmeter - 从入门到放弃_第42张图片
Jmeter - 从入门到放弃_第43张图片
(9)自定义插件调用 dubbo 接口
Jmeter - 从入门到放弃_第44张图片

4 BeanShell 断言及前后置处理

4.1 BeanShell 断言

BeanShell 是一种完全符合 Java 语法规范的脚本语言,可执行标准的 Java 语句并且又拥有自己的一些语法和方法。

4.1.1 基础断言:断言接口是否调用成功

Jmeter - 从入门到放弃_第45张图片

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


String returnData = prev.getResponseDataAsString();		// 获取返回的JSON对象
JSONObject jsonObject = JSONObject.parseObject(returnData);		// 解析返回的JSON对象
String success = jsonObject.getString("success");		// 获取JSON对象中 success 字段的值

if (success.equals("true")) {
    Failure = false;	// 断言成功
}
else{
	Failure = true;		// 断言失败
	String errorMsg = jsonObject.getString("errorMsg");
 	FailureMessage = "回调失败,errorMsg:"+errorMsg;	// 断言失败的文本信息
}

4.1.2 断言字段是否为空

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

String returnData = prev.getResponseDataAsString();
JSONObject jsonObject = JSONObject.parseObject(returnData);

String success = jsonObject.getString("success");

if ("true".equals(success)) {
	JSONObject body = jsonObject.getJSONObject("body");
	String accountId = body.getString("accountId");
	if(accountId==null || "".equals(accountId)){		// 判断 accountId 是否为null 或为空
		Failure = true;
	 	FailureMessage = "反参中 accountId 为空";
	} else {
    		Failure = false;
	}
} else {
	Failure = true;
	String errorMsg = jsonObject.getString("errorMsg");
 	FailureMessage = "回调失败,errorMsg:"+errorMsg;
}

4.1.3 断言数组不为空

Jmeter - 从入门到放弃_第46张图片

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

String returnData = prev.getResponseDataAsString();
JSONObject jsonObject = JSONObject.parseObject(returnData);

String success = jsonObject.getString("success");

if ("true".equals(success)) {
	JSONArray body = jsonObject.getJSONArray("body");	// 获取JSON对象中“body”数组
	if(body.size()>0){		// 判断body是否为空
   	 	Failure = false;
	}else{
		Failure = true;
 		FailureMessage = "该账号银行卡列表为空";
	}
} else {
	Failure = true;
	String errorMsg = jsonObject.getString("errorMsg");
 	FailureMessage = "回调失败,errorMsg:"+errorMsg;
}

4.1.4 断言多个字段不为空

JSONObject jsonObject= content.getJSONObject(0);
String caseId = jsonObject.getString("id");
String caseNumber = jsonObject.getString("caseNumber");
String personalName = jsonObject.getString("personalName");

Map map = new HashMap();	// jmeter beenshell 中 map 这样使用即可,也不需要引用 jar 包
map.put("案件id",caseId);
map.put("申请号",caseNumber);
map.put("客户姓名",personalName);

// 循环判断值是否为空
for(String key : map.keySet()){
	String value = map.get(key);
	if(value == null){
		Failure =true;
		FailureMessage = key+"为空";
	}
}

4.2 设置环境变量

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

String returnData = prev.getResponseDataAsString();
JSONObject jsonObject = JSONObject.parseObject(returnData);
JSONArray body = jsonObject.getJSONArray("body");

String bankName = body.getJSONObject(0).getString("bankName");	// 获取 body数组中第一个 JSON对象中 bankName字段的值

vars.put("bankName",bankName);	// 设置 bankName 为环境变量

4.3 设置全局变量

全局变量通过 __setProperty 函数

${__setProperty(orderNo,${orderNo},)};		// 将环境变量 orderNo 设置为全局变量

Jmeter - 从入门到放弃_第47张图片
通过 ${__P(orderNo,)} 来引用

{
	"batchNo": "${batchNo}",
	"orderNo": "${__P(orderNo,)}",
	"repayType": "00"
}

4.4 打印日志

//打印日志
log.info("INFO 级别日志"));
log.error("ERROR 级别日志");

5 函数助手

5.1 常用函数

5.1.1 获取当前系统时间:__time

Jmeter - 从入门到放弃_第48张图片

5.1.2 生成UUID :__UUID

UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,目的是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。
Jmeter - 从入门到放弃_第49张图片

5.2 自定义函数助手

5.2.1 配置 Jmeter 依赖文件

版本根据你 Jmeter 版本来决定,我的版本是5.1.1


    UTF-8
    5.1.1


    org.apache.jmeter
    ApacheJMeter_core
    ${jmeter.version}


    org.apache.jmeter
    ApacheJMeter_java
    ${jmeter.version}


    org.apache.jmeter
    ApacheJMeter_functions
    ${jmeter.version}

5.2.2 函数实现

(1)新建 class,注意 class 的上级目录是 functions ,且不能直接建在 java 目录下,否则 Jmeter 不能识别
Jmeter - 从入门到放弃_第50张图片
(2)class 继承父类 AbstractFunction ,并 alt+enter 实现其方法补齐
Jmeter - 从入门到放弃_第51张图片
Jmeter - 从入门到放弃_第52张图片
(3)KEY 命名函数名称,getReferenceKey 返回函数名称
Jmeter - 从入门到放弃_第53张图片
在这里插入图片描述
(4)desc 设置入参名称,getArgumentDesc 返回入参名称
Jmeter - 从入门到放弃_第54张图片
Jmeter - 从入门到放弃_第55张图片
(5)setParameters 获取 Jmeter 输入的入参
Jmeter - 从入门到放弃_第56张图片
Jmeter - 从入门到放弃_第57张图片
(6)execute 执行函数并返回结果
Jmeter - 从入门到放弃_第58张图片
Jmeter - 从入门到放弃_第59张图片
(7)打包部署
在命令行输入:mvn package
打包成功后会在 target 目录生成 jar 包
将 jar 包放置 \jmeter\lib\ext 目录下
在这里插入图片描述
Jmeter - 从入门到放弃_第60张图片
Jmeter - 从入门到放弃_第61张图片
(8)源码
Jmeter - 从入门到放弃_第62张图片

6 Jmeter 自定义插件

6.1 Jmeter 执行 shell 命令

插件源码:https://github.com/yciabaud/jmeter-ssh-sampler
不过该插件不支持 jmeter-5.1.1 版本,启动时会报错,但支持 jmeter-4.0 版本
(1)通过 idea 打成 jar 包后,放入\jmeter\lib\ext 目录下
Jmeter - 从入门到放弃_第63张图片
(2)SSH Command 界面介绍
Jmeter - 从入门到放弃_第64张图片
Jmeter - 从入门到放弃_第65张图片

6.2 Jmeter 发送 kafka 消息

插件源码:https://github.com/BrightTag/kafkameter
(1)通过 idea 打成 jar 包后,放入\jmeter\lib\ext 目录下
Jmeter - 从入门到放弃_第66张图片
(2)新建一个 JAVA Request,选在 Classname:co.signal.kafkameter.KafkaProducerSampler
Jmeter - 从入门到放弃_第67张图片
Jmeter - 从入门到放弃_第68张图片
(3)确认入参 kafka_brokers、kafka_topic,在代码或配置文件中确认
Jmeter - 从入门到放弃_第69张图片
Jmeter - 从入门到放弃_第70张图片

(4)填写发送的kafka信息
Jmeter - 从入门到放弃_第71张图片

引用

自定义函数助手引用:https://www.jianshu.com/p/caf55b8ceb42

你可能感兴趣的:(Jmeter)