安装
下载
安装jmeter的之前必须先装有JDK
官网下载地址:https://archive.apache.org/dist/jmeter/binaries/
jmeter3.0的对应jdk1.7,jmeter4.0对应jdk1.8以上,否者启用jmeter也会报错
配置
配置环境变量
在系统变量PATH上加上:
%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar; %JMETER_HOME%\lib\jorphan.jar; %JMETER_HOME%\lib\logkit-2.0.jar;
汉化配置
打开jmeter文件目录下的bin目录的jmeter.properties
,查找language=
,将language
修改为language=zh_CN
启动
双击jmeter目录下的bin目录下的jmeter.bat
运行jmeter.bat
的时候会出现cmd命令行窗口,这个窗口不能关闭,关闭之后会直接jmeter
基本使用
基本要素:
- 测试计划:项目名称
- 线程组:测试进程
- HTTP请求:需要压测的接口
工具栏部分功能说明
创建基本压测脚本
1.创建线程组
测试计划 ==> 鼠标右键 ==> 添加 ==> Threads ==> 线程组
线程组配置
参数 | 说明 |
---|---|
线程数 | 虚拟用户数量,一个线程代表一个虚拟用户数 |
Ramp-Up Period(in seconds) | 设置多长时间将线程数启动完毕。如果线程数为10,准备时长为5,则代表5秒内启动10个线程,即每秒启动2个线程 |
循环次数 | 每个线程发送请求的次数。如果线程数为10,循环次数为5,则每个线程发送5次请求,总的请求(并发)为10*5=50。如果勾选了“永远”,则所有线程会一直执行,直到手动选择停止运行(最后一次运行结果是报错的) |
持续时间 | 线程组发送请求持续的时间 |
启动延迟 | 线程组延迟多久后启动 |
2.创建HTTP请求
线程组 ==> 鼠标右键 ==> 添加 ==> Sampler ==> HTTP请求
HTTP配置
请求参数类型中的parameter、Body Data和Files Upload这三个只能选其中一个,不能混合使用
请求头设置
当请求参数是json格式时,需要额外设置请求头的Content-Type
:
线程组 ==> 添加 ==> 配置元件 ==> HTTP信息头管理器
响应断言(可加可不加)
JSON 断言
HTTP请求 ==> 鼠标右键 ==> 添加 ==> 断言 ==> JSON Assertion
一般选断言返回的json数据
JSON表达式,可以参考:https://gotest.hz.netease.com/doc/jie-kou-ce-shi/xin-zeng-yong-li/can-shu-xiao-yan/jsonpi-pei/jsonpathyu-fa.html
断言持续时间
用来断言请求响应的时间,即使请求成功,如果超过了持续断言时间设置的值,那么该请求会被认为请求失败
在断言中配置响应的最大时间:
3.添加查看结果树
结果树可以查看每个请求的请求信息和响应信息
线程组 ==> 添加 ==> 监听器 ==> 查看结果树
绿色的为请求成功,红色的为请求失败,判断依据为添加的响应断言
结果树取样结果参数说明
参数 | 说明 |
---|---|
Thread Name | 发送的线程名称 |
Sample Start | 发送时间 |
Load time | 加载时间,整个请求的消耗时间,从发送到接收完成全程消耗的时间 |
Connect Time | 建立连接时间 |
Latency | 等待时长,从请求发送到开始接收响应时的时间 |
Size in bytes | 发送数据的大小 |
Headers size in bytes | 请求头大小 |
Body size in bytes | 请求体大小 |
Sample Count | 请求发送数量 |
Error Count | 请求失败数量 |
Data type | 数据类型 |
4.添加聚合报告
聚合报告是本次测试的总体报告
线程组 ==> 添加 ==> 监听器 ==> 聚合报告
聚合报告
报告参数说明:
参数 | 说明 |
---|---|
Label | 请求名 |
#Samples | 并发数(线程数*循环次数) |
Average | 平均响应时间 |
Median | 中位数,50%请求的响应时间 |
90% | 90%请求的响应时间 |
95% | 95%请求的响应时间 |
99% | 99%请求的响应时间 |
Min | 最小响应时间 |
Max | 最大响应时间 |
Error% | 在#Samples并发数量下的请求的错误率 |
Throughput | 吞吐量 |
Recived KB/sec | 每秒从服务器接收的数据量 |
Sent KB/sec | 每秒发送给服务器的数据量 |
请求参数参数化
计数器
计数器用于创建一个顺序递增的参数
线程组 ==> 添加 ==> 配置元件 ==> 计数器
计数器配置
与每用户独立的跟踪计数器:每个请求独立一个计数器,当线程组有设置循环次数时,每个请求循环请求的计数器是独立的,都是从初始值根据递增值进行递增。如果不勾选该选项,则所有请求共用该计数器。
Maximum value:计数的最大值,当前的值由计数器计算下一次递增后超过最大值,则后面所有的请求都是当前的值,会从初始值重新开始递增。如初始值为1,递增为2,最大值为10,则计数器达到9的时候,下一次递增的值为11,超过了最大值10,则下一次计数从1开始重新递增
计数器使用
在HTTP请求中的请求参数,或者路径上都可与使用该计数器的值,使用的方式为:${计数器定义引用名称}
,如计数器定义的引用名称为num
,则可以使用${num}
来代表引用了计数器的值,需要注意的是,参数的数据类型,如果是字符串的话需要自行使用双引号包住引用的值
CSV数据文件
即引用外部数据文件来实现参数化
线程组 ==> 添加 ==> 配置元件 ==> CSV数据文件设置
CSV数据文件说明
csv文件跟Excel文件一样都是表格,除非可以创建csv文件,否则由Excel改后缀转成csv,读出来的数据都是乱码。解决方式是直接使用txt文件。内容如:
多列使用英文逗号隔开
CSV数据文件配置
变量名称:与数据文件中的表头无关,这里的变量名称是用来定义在线程组中使用该数据的变量名(读取数据文件是通过顺序读取,从左到右,所以需要保证数据文件的每一列数据对应上需要的变量名称),多个使用英文逗号隔开
CSV数据文件使用
- 与计数器的使用相同,在HTTP请求中的请求参数,或者路径上都可与使用CSV配置中的变量名称,也是同样
${变量名称}
的使用方式,也需要注意请求参数的数据类型 - 当数据文件中数据行数比并发量小的时候,会从头循环数据文件中的数据。如:并发数为5,数据文件只有3行,第一个请求用数据文件第一行的数据,第二个请求用数据文件第二行的数据,第三个请求用数据文件第三行的数据,当第四个请求发起的时候,数据文件没有第四行的数据,则会从第一行开始读起
其他常用组件
HTTP Cookie管理器
在请求中经常会遇到需要Cookie的场景,如登录后的tokenid存放在Cookie,可以使用HTTP Cookie管理器为来添加Cookie
线程组 ==> 添加 ==> 配置元件 ==> HTTP Cookie管理器
HTTP Cookie管理器配置
根据自己的需求添加Cookie即可,Cookie中的值也可以使用全局的变量名称来实现动态变化
HTTP请求默认值
如果多个请求的服务器地址、端口、协议都是同一个,可以使用HTTP请求默认值来处理
线程组 ==> 添加 ==> 配置元件 ==> HTTP请求默认值
HTTP请求默认值配置
像配置HTTP请求一样,但不需要填写请求路径
后续填写HTTP请求时就不需要再填写协议、服务器地址、端口号和连接编码格式,只需要填写请求路径和请求方法即可
如果Body Data中填写了共同参数,则请求会把这个请求参数拼入请求体中,但需要注意填写的格式,如上图HTTP请求默认值中填写了json格式的共同参数,包含了
current
和pageSize
两个参数,而HTTP请求中有独自请求参数,那最终的请求结果为:
请求体变成了:
{ "studentName": "张三" }{ "current": 1, "pageSize": 10 }
(目前想到的解决办法是各写一半,默认请求写下半段:
"current": 1,
"pageSize": 10
}
HTTP请求写上半段
{
"studentName": "${studentName}",
但这似乎有些另类并且不好维护)
定时器
当并发请求需要间隔时间发起请求时,可以使用定时器,这里介绍两种定时器
固定定时器
固定延迟指定时候后发起请求
线程组 ==> 添加 ==> 定时器 ==> 固定定时器
Uniform Random Timer定时器
随机定时器,随机延迟后发起请求,总体延迟时间 = 随机时间 + 常量时间
线程组 ==> 添加 ==> 定时器 ==> Uniform Random Timer
Uniform Random Timer配置
其他常见场景
多个请求顺序执行
在Jmeter中,在同一个线程组内,设置的请求是从上到下顺序执行的,也就是排得越靠顶部,越优先执行
使用上一个请求的请求结果作为下一个请求的请求参数
因为同一个线程组内,设置的请求是顺序执行的,经常会出现使用上一个请求的请求结果,作为下一个请求的请求参数。下面以新增后,根据新增的id进行详情查询为例讲解如何实现:
HTTP请求默认值:
新增的HTTP配置
- 添加JSON Extractor
在新增请求上 ==> 右键 ==> 添加 ==> 后置处理器 ==> JSON Extractor
- 配置JSON Extractor
JSONPath表达式参考:https://gotest.hz.netease.com/doc/jie-kou-ce-shi/xin-zeng-yong-li/can-shu-xiao-yan/jsonpi-pei/jsonpathyu-fa.html
- 添加JSON Extractor
根据id查询详情的HTTP配置
在请求参数中,使用
${}
来使用动态变量,这里使用${studentId},对应JSON Extractor中的的自定义变量名称测试结果:
第一个请求的响应:
第二个请求的请求参数:
多个不同请求同时并发执行
一个测试计划下面可以有多个线程组,如果选择了工具类上的启动,则会启动所有的线程组,每个线程组的请求都是互不影响的。如果有多个请求不同请求同时并发的话,可以选择创建多个线程组来实现
一些JSONPath表达式
json数据体:
{ "code":200, "data":{ "type":"String", "name":"userName", "value":"张三" } }
获取到data中value的值:
$.data.value
json数据体:
{ "code":200, "data":[ { "type":"String", "name":"userName", "value":"张三" }, { "type":"Integer", "name":"age", "value":18 } ] }
获取到data数组中,第一个元素的value值
$.data[0].value
json数据体:
{ "code":200, "data":[ { "type":"String", "name":"userName", "value":"张三" }, { "type":"Integer", "name":"age", "value":18 } ] }
获取到name为userName的value的值:
$.data[?(@.name=="userName")].value
json数据体:
{ "code":200, "data":{ array:[ { "type":"String", "name":"userName", "value":"张三" }, { "type":"Interger", "name":"age", "value":18 } ] } }
获取到array数组中name为age的value的值:
$.data.array[?(@.name=="age")].value