jmeter+exexl实现接口自动化
文章目录
- jmeter+exexl实现接口自动化
- JMETER介绍
- jmeter环境安装
- jmeter中exexl定义字段
- JMETER的接口自动化
- 1. 创建线程组 ,定义全局域名和全局变量,
- 2.创建jdbc 连接mysql数据库
- 3. 创建线程组,将execl中数据循环读取并在https请求执行
- 创建个循环控制器,循环读取execl中数据, 循环次数勾上
- 在 循环控制器 中配置元件添加个 CSV数据文件设置
- 在 循环控制器 中配置元件添加个 HTTP信息头管理器
- 在 循环控制器 中配置元件添加 如果(if)控制,是来判断多个https请求 和 execl中use中判断是否是1或者0
- 在 如果(if)控制 创建个 http请求 为 GET请求方式,在服务器或ip填写 读取execl域名字段 `(${__eval(${url})} `
- 接口之间肯定涉及到 token 相传,所有得弄个 BeanShell 前置处理器进行处理,将提取token进行传入到我们之前设定的 HTTP信息头管理器里面
- 在创建个BeanShell 前置处理器进行处理 JSON提取器为空和 数据库为空 报错,当为空设置默认值
- 在创建个 响应断言。进行判断接口返回数据是否在 预期接口一致,取execl中 `${expected_results}` 字段
- 在创建个 json提取器,在接口返回的参数提取出来,给下个接口进行使用
- 在创建个接口等待时间,固定定时器进行等待
- 断言使用响应断言并不满足,需要对指定参数进行判断,增加个 BeanShell断言进行判断
- 在创建个 前置数据库操作,有时候接口的参数不想写死,可以在数据库中取就可以进行前置数据库实现
- 在创建个 后置数据库操作,有时候接口返回参数数据是否正确,可以在数据库查询结果然后跟接口返回的参数进行对比
JMETER介绍
Apache JMeter是 100%的java桌面应用程序。它可以被用来测试包括基于静态和动态资源程序的性能,
JMeter可以模拟大量的服务器负载、网络负载、软件对象负载,可以在不同压力类别下测试软件的强度,以及分析软件的整体性能,并提供图形化的性能分析。
JMeter 能够通过让你们用断言创造测试脚本来验证我们的应用程序是否返回了我们期望的结果,从而帮助我们回归测试我们的程序。为了最大的灵活性,JMeter 允许我们使用正则表达式创建断言,功能也非常强大。
jmeter环境安装
- 安装jdk环境,配置好java环境 java安装地址
- 安装jmeter,jmeter是java编写,需要jdk支持 jmeter安装地址
jmeter中exexl定义字段
id | event | title | use | method | url | api | request_header | request_body | json_path_name | json_path | json_path_mach_no | json_path_default | expected_results | jsonpath | jsonpath_results | sleep | mysqlname | sqlnames | setup_sql | teardown_sql |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
用例id | 用例模块 | 用例名称 | 用例执行条件,0为不执行,1为执行 | 接口请求方式 | 接口请求域名 | 接口请求路径 | 接口请求header参数 | 接口请求body参数 | jsonpath提取名称 | jsonpath提取方法 | jmete中json提取器Match no: 0随机;n取第几个匹配值;-1匹配所有,后续引用 变量名_N 取第N个值 | jmete中json提取器Default values 默认值 | jmeter中响应文本判断 | jsonpath提取结果跟jsonpath_results | 跟jsonpath提取比较 | 接口等待时间 | mysql数据库中那个库 | sql中提取的命名 | 前置sql处理 | 后置sql处理 |
JMETER的接口自动化
1. 创建线程组 ,定义全局域名和全局变量,
创建全局域名,在线程中 的配置元件创建个用户定义变量,在execl中 url字段引用域名 使用 jmeter中 全局调用 ${baidu}
2.创建jdbc 连接mysql数据库
创建连接数据库,在线程中 的配置原件 创建个 JDBC Connection Connection 根据你自己mysql 填写数据
3. 创建线程组,将execl中数据循环读取并在https请求执行
创建个循环控制器,循环读取execl中数据, 循环次数勾上
在 循环控制器 中配置元件添加个 CSV数据文件设置
在 循环控制器 中配置元件添加个 HTTP信息头管理器
在 循环控制器 中配置元件添加 如果(if)控制,是来判断多个https请求 和 execl中use中判断是否是1或者0
在 如果(if)控制 创建个 http请求 为 GET请求方式,在服务器或ip填写 读取execl域名字段 (${__eval(${url})}
http请求值就为 GET
路径就取 exec字段的 ${__eval(${api})}
如果域名想做多个环境考验运行可以这样写:
在用户自定义变量 域名写 ${test}-baidu.com
在创建个用户自定义表 定义一个 text的值 为 sit 这时候在 服务器或ip填写 读取execl域名字段为 ${__eval(${__eval(${url})})}
需要多个eval 去获取变量
接口之间肯定涉及到 token 相传,所有得弄个 BeanShell 前置处理器进行处理,将提取token进行传入到我们之前设定的 HTTP信息头管理器里面
import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.control.Header;
import org.apache.jmeter.protocol.http.sampler;
import org.json.JSONObject;
//sampler 里面有个getHeaderManager 可以获得请求头
HeaderManager hm =sampler.getHeaderManager();
List CSVHeaderKey = new ArrayList();
//将header 转为jsonobject
String header = "{\"workbench-authorization\":\"${manager_authorization}\"}";
log.info("CSV获取到要添加的请求头:"+header);
String header = "${__eval(${__eval(${request_header})})}";
log.info("CSV获取到要添加的请求头:"+header);
//CSV里面的request_header 不为空才添加
if (header != null && header.length() != 0)
{
JSONObject header_obj= new JSONObject(header);
Iterator it = header_obj.keys();
while(it.hasNext()){
//获得key
String key = it.next();
String value = header_obj.getString(key);
CSVHeaderKey.add(key); //把添加的放到一个list,在后置处理器删除
Header hd = new Header();
hd.setName(key);
hd.setValue(value);
//加入sample中
hm.add(hd);
}
}
//用于后置处理器删除添加的header
//因为添加的请求头会用到下一个请求,当重复添加,请求头里就有多个同样的请求头,所以需要删除每次添加的请求头
log.info("获取的参数:"+CSVHeaderKey.toString());
log.info("${__eval(${mysqlname})}");
vars.put("HeaderKey", CSVHeaderKey.toString());
在创建个BeanShell 前置处理器进行处理 JSON提取器为空和 数据库为空 报错,当为空设置默认值
取execl中 mysqlname
和 sqlnames
判断为空 就将前置sql 和 后置sql 设置为 默认条件
取execl中 json_path_name
和 json_path
判断为空 就将提取的字段设置为默认
// 如果数据库为空,就设置默认值
if("${__eval(${mysqlname})}" == "" || "${__eval(${sqlnames})}" == ""){
vars.put("mysqlname","text");
vars.put("setup_sql","select * from `user` limit 1");
vars.put("teardown_sql","select * from `user` limit 1");
}
// 如果JSON提取器为空,就设置默认值
if("${__eval(${json_path_name})}" == "" || "${__eval(${json_path})}" == ""){
vars.put("json_path_name","$.*");
vars.put("json_path","1");
vars.put("json_path_mach_no","1");
vars.put("json_path_default","null");
}
在创建个 响应断言。进行判断接口返回数据是否在 预期接口一致,取execl中 ${expected_results}
字段
在创建个 json提取器,在接口返回的参数提取出来,给下个接口进行使用
取execl 中:
json_path_nam
提取的名称,注意:提取名称不要命名一致
json_path
提取参数 jsonpath语法
json_path_mach_no
:随机;n取第几个匹配值;-1匹配所有,后续引用 变量名_N 取第N个值
json_path_default
: 默认值,匹配不到值的时候取该值
在创建个接口等待时间,固定定时器进行等待
取execl 中 sleep 字段
断言使用响应断言并不满足,需要对指定参数进行判断,增加个 BeanShell断言进行判断
取execl 中 jsonpath
和 jsonpath_results
jsonpath 对接口返回的参数 编辑jsonpath进行提取
jsonpath_results : 对接口返回的参数 填写个预期的接口
有个问题 为啥有 响应断言 为啥要做 jsonpath进行断言,响应断言一般可以写死,写对 code 和msg进行判断,但是单单判断这些比不满足,会出现接口返回成功但是数据并没有返回这种问题,所有需要专门对预期的参数进行判断
import com.alibaba.fastjson.JSONPath;
try{
if("${jsonpath}" != "" &&"${__eval(${__eval(${jsonpath_results})})}" != "" ){
String responseString = prev.getResponseDataAsString();
String jsonpath_results = "${__eval(${__eval(${jsonpath_results})})}";
String getJsonPath ="${jsonpath}";
String getJsonPathDate = JSONPath.read(responseString,getJsonPath).toString();
log.info("JsonPath表达式:"+getJsonPath+" ,获取到的值:"+getJsonPathDate+",预期结果值:" + jsonpath_results);
if(getJsonPathDate.equals(jsonpath_results)){
Failure = false;
FailureMessage = "获取jsonpath断言结果:断言成功,获取到的值:"+getJsonPathDate+",预期结果值:" + "${__eval(${__eval(${jsonpath_results})})}";
}else{
Failure = true;
FailureMessage = "获取jsonpath断言结果:断言失败,获取到的值:"+getJsonPathDate+",预期结果值:" + "${__eval(${__eval(${jsonpath_results})})}";
}
}
}catch(Exception e){
Failure = true;
FailureMessage = "JSONPATH 获取值失败,请检查输入的语句是否能获取值:" + "${jsonpath}" + ",预期的结果为:" +"${__eval(${__eval(${jsonpath_results})})}" ;
}
在创建个 前置数据库操作,有时候接口的参数不想写死,可以在数据库中取就可以进行前置数据库实现
需要将execl中 mysqlname
setup_sql
sqlnames
进行存放
mysqlname 值连接那个数据库的库名称
setup_sql mysql的 sql查询等
sqlnames 查询的参数进行命名然后给下个接口使用
在创建个 后置数据库操作,有时候接口返回参数数据是否正确,可以在数据库查询结果然后跟接口返回的参数进行对比
需要将execl中 mysqlname
setup_sql
sqlnames
进行存放
mysqlname 值连接那个数据库的库名称
teardown_sqlmysql的 sql查询等
sqlnames 查询的参数进行命名然后给下个接口使用
大体的jmeter 接口自动化流程就是这样,后面也可以创建对应的 post put
请求方式,如遇到什么问题可以进行联系