JMeter,Apache基金会的一款测试工具,主要用于接口测试。
安装
Java环境
JMeter需要运行在Java环境上。
我们更多的时候,是在Windows或者MacOS上运行JMeter,关于Java环境的安装,可以参考《基于Java的后端开发入门:1.基础语法》的"环境与工具准备"部分,有讨论Windows和MacOS上怎么安装Java。
至于在Linux上安装Java,可以参考《ElasticSearch实战入门(6.X):1.工具、概念、集群和倒排索引》的"准备JDK"部分。
下载
我们通过官网下载JMeter,地址:https://jmeter.apache.org/
下载之后,直接进行解压即可,这是一款"绿色版"软件。
解压后内容如下:
修改字符集
首先,我们需要修改JMeter的默认字符集,否则可能会出现中文乱码。
打开bin
目录下的jmeter.properties
,找到如下部分
1 | # The encoding to be used if none is provided (default ISO-8859-1) |
修改字符集为UTF-8
1 | UTF-8 = |
启动
在bin
目录下,有三个启动文件。分别是:
ApacheJMeter.jar
:图形化启动jmeter.bat
:Windows下的命令行启动jmeter.sh
:Linux下的命令行启动
图形化启动后,界面如下:
快速开始
添加线程组
右键点击测试计划
,依次选择线程
、添加线程组
。
HTTP请求
右键点击线程组
,依次选择取样器
、HTTP请求
。
例如,对于GET请求"http://127.0.0.1:8080/ssm/books/1",填写如下:
查看结果树
右键点击测试计划
,依次选择添加监听器
、查看结果树
。
运行,查看结果
我们点击箭头所示的地方,运行。
然后点击查看结果树
。对于响应结果,如果是JSON格式的话,点击图示的JSON,可以看得更清楚。
对于结果记录,可以通过点击箭头所示的地方,进行清除。
重命名
当然,我们可以对"测试计划"、“线程组”、"HTTP请求"等进行重命名。
线程组
线程
关于什么是线程,可以参考我们在《基于Java的后端开发入门:7.多线程 [1/2]》的"什么是多线程"部分。
在这里,结合Jmeter的实际操作及其应用场景等,更直观的是把线程看成用户。
那么什么是线程组呢?
一个进程中有许多线程,为了方便管理,我们对线程按照性质分组,分组的结果就是线程组。
即,一个进程可以包含多个线程组,一个线程组可以包含多个线程。
并发和顺序
- 并发执行:多个线程同时执行。
- 顺序执行:多个线程顺序执行。
我们创建一个测试计划如下
在创建过程中,可以用复制粘贴的方式。需要注意的是,我们需要选中父级进行粘贴。
例如,我们在选中HTTP请求进行复制,需要选中线程组进行粘贴。
然后我们点击执行。
结果如下:
这是并发执行。
同时我们看到,线程组是并发,但是线程组中的每个线程是顺序。
如果我们勾选独立运行每个线程组,则线程组也是顺序了。
(独立运行线程组的功能,不仅仅是设置线程组顺序执行。)
特殊的线程组
在我们创建线程组的时候,还会发现两个特殊的线程组。
setup线程组
,一定会首先执行。teadDown线程组
,一定会最后执行。
线程组的设置
- 线程数:模拟的用户个数。
- Ramp-Up时间:循环在多久完成。
- 循环次数:这个就是循环次数。
如果我们循环次数勾选永远,但是我们只想在一分钟内永远。怎么配置?
我们勾选调度器,并在持续时间处填60。
调度器中,还有一个参数,启动延迟,这个很好理解,我们启动之后,先延迟指定的时间,
HTTP相关
HTTP请求默认值
在上文,我们设置了很多HTTP请求,这些HTTP请求的协议、端口等都是一样的。
我们可以配置默认值,按照如下的方式,打开"HTTP请求默认值"。
在配置HTTP请求的默认值,如果新建的HTTP请求,有没配置的值,会利用默认值。
HTTP信息头管理器
按照如下的方式,打开HTTP信息头管理器
关于HTTP的header的参数,我们不做太多讨论,有部分重要的HTTP的header,可以参考我们在《基于Java的后端开发入门:14.HttpClient》的讨论。
配参数
常见的配参数方式有四种
1、用户定义的变量
2、CSV数据文件设置
3、用户参数
4、函数
用户定义的变量
配置元件,用户自定义变量。
例如,我们配置变量名id
,值为123
。
然后我们在路径中配置${id}
试一下
CSV数据文件设置
设置方法
配置元件,CSV数据文件设置。
弹出窗体,我们配置变量名为id
,如果我们的CSV文件有多列,则配置多个变量名。
线程共享模式
在上图,我们注意到,还有一个线程共享模式。
假设数据内容为:1
,2
,3
,4
,5
,6
。
所有线程
所有线程组的每个线程每次循环都将读取一条新的数据。
当前线程
线程在每次循环时才读取一条新的数据。
当前线程组
数据读取情况与设置为"所有线程"一致,只是测试计划中有多个线程组时,每个线程组都从数据文件第一条数据开始读取。设置为"所有线程"时,后面线程组是接着前面线程组读取完数据的位置接着往下读取。
用户参数
前置处理器,用户参数:
例如,我们设置了3个用户,如下:
当线程组的线程数为2,循环次数为2,则结果是:用户一
、用户二
、用户一
、用户二
。
当线程组的线程数为3,循环次数为1。则三个用户都会有。
当线程组的线程数为5,循环次数为1。则:用户一
、用户二
、用户三
、用户一
、用户二
。
函数
我们以counter
函数为例,讨论函数的用法。
函数菜单:
选择函数,配置函数参数,点击生成。
生成的内容,复制粘贴,这样就可以直接调用了。
Jmeter的函数很多,例如:Random
,随机数;time
,获取当前时间。
断言
断言分很多种,这里我们以响应断言和断言持续时间为例。
响应断言
断言,响应断言。
“响应文本”,包括,“Spring”。
如果断言为否,我们会看到标红。
此外,还有,响应代码,这种方式即匹配HTTP的状态码。
断言持续时间
断言、断言持续时间。
例如,我们设置持续时间为10毫秒。
则,大于10毫秒的会标红。
逻辑控制器
IF控制器
逻辑控制器,IF控制器。
类似于编程语言中的IF,IF为真时需要执行的内容,要在IF控制器的内部。
我们把箭头处的勾选去掉
我们填写的逻辑是
1 | "${id}" < "10" |
其中双引号是固定格式,必须这么填。
循环控制器
逻辑控制器,循环控制器。
设置方法也很简单,设置循环次数即可。
那么,这个和线程组的循环有什么区别呢?
例如,我们在线程组中有两个HTTP请求,第一个我们想执行10次,第二个我们只想执行5次。
这时候就不能用线程组的循环了,线程组的循环是全局生效的,得用循环控制器。
ForEach控制器
逻辑控制器,ForEach控制器。
定义用户的变量,如下
ForEach控制器的设置如下
高并发
同步定时器
场景:100位用户同时访问系统,统计高并发情况下平均响应时间以及错误率等。
因为100位用户,所以线程组要配置100个线程。
那么,同时怎么办?
定时器,同步定时器。
因为是100位用户同时,所以"模拟用户组的数量",也填100。
如果我们是100人,每次50次同时,则"默认用户组的数量"填50。
(“模拟用户组的数量”,这个名字让人容易看不懂,其含义实际就是 每组用户数。)
聚合报告
我们还需要统计平均响应时间以及错误率等。这时候不能再用之前的"查看结果树"这个监听器了,要用"聚合报告"。
监听器,聚合报告。
点击运行后,聚合报告内容如下
特别的,我们可以在HTTP请求的名字上加上参数。
这样,我们更容易看到具体是哪一个参数查询较慢。
高频率
场景:一位用户以20QPS(20次/秒)的频率访问系统,持续15秒,统计服务器的平均响应时间。
高频率,需要用到 常数吞吐量定时器 。
常数吞吐量定时器的设置:
因为我们是每秒20次,那么每分钟就是1200次,即目标吞吐量是1200。
那么,怎么控制15秒呢?
20次每秒,持续15秒,所以总次数是300次。
即在线程组设置循环次数:300。
测试结果,同样需要通过聚合报告
看。
弱压力
场景:半小时内,1000位用户访问系统。这就是所谓的弱压力测试。
1000个用户,所以线程组的线程数写1000。
那么半个小时怎么设计?线程组的Ramp-Up填1800。
测试数据库
最后一个话题,JMeter还可以直接对数据库进行测试。
加载JDBC驱动
和我们常见的Java程序一样,JMeter也是用JDBC去连接数据库的。
点击浏览,选择数据库的JDBC驱动。
连接数据库
配置元件,JDBC Connection Configuration。
其中,Variable Name for created pool
填写我们数据库连接池的名称。
其他的属性,可以参考我们在《基于Java的后端开发入门:10.JDBC》的讨论。
JDBC-Request
取样器,JDBC-Request。
需要注意的是,在JDBC-Request的配置页面,有一个Query Type
,我们选择对应的类型。