学习视频
B站UP主:白月黑羽编程
目录
Jmeter的下载
Jmeter界面
Jmeter操作
线程组与HTTP请求
测试一个请求
解决响应数据中 中文乱码的问题
HTTP请求默认值
录制网站流量
添加录制控制器
添加HTTP代理服务器
在浏览器配置代理
进行录制
模拟间隔时间
命令模式运行
dashboard 产生图表
编辑 Cookie管理器
消息数据关联
变量
后置处理器
实现
CSV 数据文件设置
断言
循环控制器
预处理器
Jmeter的下载
在下载Jmeter之前需要先下载JDK
JDK下载地址
建议下载 JDK8 或者 JDK11 ,因为这两个版本比较稳定,于Jmeter的兼容性也比较好。
Jmeter下载地址
可以看到有一个 Binaries 下面的 JMeter程序压缩包文件 下载列表。
点击 apache-jmeter-5.x.x.zip
这样的下载链接进行下载
注意下载的Jmeter的版本要和JDK对应,版本对应关系在Jmeter下载地址中有。
下载到一个合适的目录下面,然后解压该文件到指定目录,即出现一个名为 apache-jmeter-XXX
的目录。
进入到该目录中,再进入到名为bin的目录。
如果是Windows系统:双击名为 jmeter.bat
的文件,即可打开Jmeter管理界面程序。
Jmeter界面
双击jmeter.bat
之后,会先出现一个cmd窗口,一会之后出现Jmeter的图形界面
cmd界面:以后有什么调试信息会出现在这里
图形界面:进行性能测试操作。
默认为英文界面,可以点击options->choose lauguage->chinese切换为中文
Jmeter操作
线程组与HTTP请求
性能测试是:验证 在 各种性能负载情景下,系统的表现是否符合预期。
一个性能测试场景, JMeter称之为 test plan
,中文翻译为 测试计划
。
实际上,一个 JMeter的测试计划 对应 性能测试的一个场景,其实也就是一个 测试用例
。
应该先准备好 性能测试用例, 然后再用JMeter对应配置好一个测试计划来对应它。
每个测试计划都可以保存在一个单独的文件中。
点击保存按钮,将测试计划保存到本地文件中。(注意:在修改了名称之后,要点击其他地方才会显示修改之后的结果)
JMeter的测试计划,具体里面的内容怎么测,根据你设计好的测试用例,在这个下面添加相应子节点定义。在测试计划下添加线程组,表示一组测试用例。
在线程组中可以配置
线程数表示一个用户
Ramp-Up 时间
意思是 所有用户上线的总时间,以秒为单位。
比如5,就表示总共耗时5秒,如果是 5个用户,那就意味着 每隔1.25秒上线一个: 5秒/(5-1) = 1.25
循环次数
意思是 每个用户 做线程组里面定义的动作行为 多少轮
。 缺省就做一轮。
然后再在这个测试用例下面添加要测试的HTTP请求
线程组中的多个HTTP请求从上往下依次执行。
测试一个请求
现在假如我们要测试如下请求URL
需要再HTTP请求中进行如下操作
为了查看测试的结果,我们需要再用户行为下添加一个监视器
一般选择“查看结果树”
然后先点击用户行为1,再点击上面的绿色的三角按钮,进行运行用户行为
直接点击开始,这是运行test1下面的所有行为
运行之后点击查看结果树,查看运行的结果
结果树的取样器结果中参数的意义:
Thread Name:用户行为1 1-1
Sample Start:2024-06-02 20:40:52 CST
Load time:39
Connect Time:23
Latency:35
Size in bytes:2122
Sent bytes:196
Headers size in bytes:342
Body size in bytes:1780
Sample Count:1
Error Count:0
Data type ("text"|"bin"|""):text
Response code:200
Response message:OK
HTTPSampleResult fields:
ContentType: application/json
DataEncoding: null
其中
Connect Time : jmeter 和 被测系统 建立 TCP 连接的时间,包括3路握手时间, 如果连接复用, 值为0
lantency: 从发出请求前 到 接收完第一个响应的时间
loadtime: 从发出请求前 到 接收完所有响应的时间 如果是长消息, 往往时长 >= lantency,因为有多个响应
Size in bytes : 整个消息消息大小 = Headers size in bytes + Body size in bytes Headers size in bytes : 响应消息头大小
Body size in bytes : 响应消息体大小
在每一次查看结果树之前,可以先清楚上一次的结果。
解决响应数据中 中文乱码的问题
修改Jmeter的配置文件
我们可以通过修改Jmeter的配置文件来解决中文乱码问题。具体操作步骤如下:
- 打开Jmeter的安装目录,并定位到“jmeter/bin”路径下的“jmeter.properties”文件。
- 使用文本编辑器打开“jmeter.properties”文件。
- 将该行中的“sampleresult.default.encoding=ISO-8859-1”修改为“Sampleresult.default.encoding=UTF-8”。
- 保存文件并重新启动Jmeter。
通过修改配置文件,我们可以将Jmeter的默认编码设置为UTF-8,从而解决返回结果的中文乱码问题。
HTTP请求默认值
测试过程中,被测系统换了, 就要换配置的地址, 要手动修改 请求参数,请求取样器多了, 就非常麻烦了。
可以使用HTTP请求默认值
解决这个问题。
在测试计划下面添加HTTP请求默认值:
HTTP请求默认值中的设置与HTTP请求中的相似,只是HTTP请求默认值中的属性值是作用在当前测试计划中的所有HTTP请求中,如果一个HTTP请求没有设置对应的属性,就会使用HTTP请求默认值中的属性值,如果设置了就是用自己设置的属性值。也可以在对应的线程组中配置对应的HTTP请求默认值。
修改之后的HTTP请求:
结果树:
录制网站流量
有时候,我们需要测试一个网站上面的很多URL路径,一个一个手动定义HTTP请求太麻烦,所以Jmeter提供了录制网站流量的操作,根据录制的用户操作,得到网站上面的URL请求。具体操作如下
添加录制控制器
先在一个测试计划下新创建一个线程组
然后再线程组下添加一个录制控制器
添加HTTP代理服务器
在测试计划下添加HTTP代理服务器
在浏览器配置代理
这里以Edge浏览器为例,其他浏览器也差不多
在Edge浏览器的扩展商店中进行如下操作,搜索SwitchOmega插件
代理服务器要与HTTP请求中的IP地址相同,代理端口要与HTTP代理服务器的端口相同
然后在测试的网页中点击插件,选择对应的代理
进行录制
先在Jmeter中点击HTTP代理服务器中的启动按钮,流程如下
然后进入想要录制的对应网站,选择代理,进行操作,
比如先点击首页,再点击专题,最后点击新闻
操作完成之后,点击停止
回到Jmeter中查看录制控制器
然后将这些得到的请求复制到线程组中
在线程组中点击验证,(验证只运行一次)
查看结果树
模拟间隔时间
可以使用 JMeter的 定时器 Timer
定时器 执行优先级高于取样器, 会先暂停, 可以放在下一个消息的前面
在一个线程组下面添加一个定时器,会每隔2秒按照从上往下的顺序执行这个线程组中的HTTP请求。
也可以使用 取样器 里面的 测试活动 flow control action
取样器
比如我想要模拟这样一个间隔时间:首页中的请求跑完之后,间隔2秒执行专题中的请求,专题中的请求运行完之后,间隔3秒执行新闻中的请求
实现:在专题、新闻中的请求之前添加一个测试活动,在测试活动中的Duration中设置间隔时间,单位为毫秒(ms)
命令模式运行
真正实施性能测试应该在命令行模式下运行,命令格式如下:
D:\apache-jmeter\bin\jmeter -n -t test1.jmx -l log.jtl
注意JMeter的路径替换为你的安装路径
注意:要在test1.jmx文件目录下,打开CMD窗口运行这个命令,将jmeter的路径换成自己电脑中的路径,log.jtl是测试的信息文件,后面要通过这个文件生成图表。
运行完成后,会多出两个文件,jmeter.log和logtest1.jtl
dashboard 产生图表
d:\apache-jmeter-5.4.1\bin\jmeter -g logtest1.jtl -o report1
就会产生report1目录,里面的index.html 打开就是报告
注意 -o
后面的目录 一定要不存在,或者内容为空,否则会报错。
其中 APDEX (Application Performance Index)
里面的 T (Toleration threshold)
和 F (Frustration threshold)
可以通过 JMeter 工具 bin 目录下面的 user.properties
配置文件里面 这两个选项来设置
jmeter.reportgenerator.apdex_satisfied_threshold
jmeter.reportgenerator.apdex_tolerated_threshold
Cookie管理器
上面的请求都是在没有携带数据的情况下进行测试的,但是一般的网站上,在用户登录之后的请求,都会携带cookie进行用户信息的校验。
加入现在有这样一个请求:打开登录页->进行登录后->进入首页
先使用前面录制的方式,录制后,验证一下
对比正常的请求的响应结果
可以看到这个请求是携带Cookie的,将Cookie传给后台,后台服务器读取这个Cookie值,根据存储到服务器中的用户数据返回对应的值。
这个Cookie值是在用户登录成功之后返回的数据
所以就需要让JMeter自动把接收到的 HTTP 响应消息中的 Cookie
保存起来,并且在后续发给该网站的请求中自动携带上。
可以在测试计划节点下面添加一个 HTTP Cookie管理器
然后再次验证
验证成功
消息数据关联
做API接口性能测试的时候,后面的请求参数 往往 需要 根据前面的请求结果
来决定。
这样,测试工具填入的数据就是动态的,没法预先写死。
比如前面的测试场景,后续还需要做如下操作:
用户登录后,打开 学习中心 -> 我的任务
页面,查看前2个任务。
这样,就要获取前2个任务的id, 因为每个学员 任务分配
的id都是不一样的。
JMeter 需要 从 前面 列出任务的 HTTP API响应结果 里面提取出 ID, 供后面的请求使用。
如何做到呢?
这就要使用 后置处理器
和 变量
。
变量
JMeter中,使用变量,是通过 ${变量名}
这样的格式
变量可以用户自己定义产生,也可以由前置处理器、后置处理器 等 JMeter 元件产生。
有的是JMeter内置变量,比如表示当前线程号的变量 __threadNum
,就可以这样使用 ${__threadNum}
后置处理器
JMeter 通过 后置处理器 取出 取样器响应结果中 要提出取出来的数据, 存入变量,后续请求使用这些变量。
说明文档:jmeter.apache.org
测试网页: Jayway JsonPath evaluator
实现
所以在我的任务中的请求后面添加一个后置处理器,得到返回结果中的id
将上图中的两个id取出来,传递给后面的请求
在任务1、任务2的请求参数中动态的设置Id值
结果:
和浏览器页面中显示的一致
CSV 数据文件设置
有时候,性能测试有大量的数据 需要从 CSV 格式的文件读入使用。
CSV格式的文件,其实就是文本文件,里面记录了性能测试数据,比如
sz_000001,111111
sz_000002,111111
sz_000003,111111
这时,可以在某个 线程组下面 添加 CSV data set config(CSV 数据文件设置)
元件
CSV 数据文件设置可以为每列设置一个变量名,比如上例就是 loginname,password
JMeter会把 每行数据依次分配给一个线程。
这样,每个线程里面的元件 就可以使用 这些变量 ,得到对应的数据。
然后在登录的请求哪里使用这两个变量
记得在线程组这里多设置几个线程,起码不少于data.csv文件中的数据
然后再次启动(这里就不是验证了)
断言
利用JMeter断言, 可以判定 从被测系统 收到的响应消息是否正确。
断言的有效范围是同级所有取样器,如果只需要针对某个取样器,应该添加在它下面。
例如,可以判断响应是否包含某些特定文本、数据。
甚至可以使用 Groovy、 BeanShell 这样的脚本语言做 更加灵活的断言判定。
比如下面使用 JSR223 断言
脚本,可以检查JSON格式消息体响应中的total字段值是否小于10
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper();
def retObj = jsonSlurper.parseText(prev.getResponseDataAsString());
if(retObj.total < 10){
AssertionResult.setFailureMessage("retObj.total <10");
AssertionResult.setFailure(true);
}
启动测试一下
可以看到,断言不通过的请求就会显示失败
循环控制器
线程组可以整体循环, 但是如果你只想循环 线程组其中的一部分操作呢?
比如:
用户登录一次, 后续操作循环10次,每次间隔20秒 可以使用循环控制器。
循环控制器 内部的元件有时需要用到 当前循环序号
。
JMeter 的当前循环序号放到变量 __jm__<循环控制器名称>__idx
中。
比如你的 循环控制器 名为 LC, 你就可以通过 ${__jm__LC__idx}
访问到 当前循环序号
进行验证
预处理器
预处理器 在取样器请求 发出前执行一些操作
用的比较多的是:设置一些参数、修改取样器的设置、脚本预处理
有效范围是同级所有取样器,如果只要针对某个取样器,应该添加在它下面。
常用的有 用户参数、HTML链接解析器、JSR223/BeanShell 等前置处理器
比如,下面JSR223前置处理器的代码可以把一个 当前循环序号变量值进行预先处理 加1。
long number = Long.parseLong(vars.get('__jm__LC__idx'))
number = number + 1;
vars.put('loopno',String.valueOf(number))
// OUT.println vars.get('loopno')//将调试信息输出到CMD窗口
验证
....................................................................结束啦.........................................................................
遗留问题:
(1)只能录制自己本地的网站流量(就是ip地址为localhost),录制不了公网上的一些网站流量(比如百度这些网站),是我代理没有配置正确的问题吗?并且在配置代理之后就不能上网了。
(2)在消息数据关联哪里,如果前一个请求返回的结果个数不确定,要怎么动态的得到上一个请求的参数,传递给后面的请求嘞?
有人能解答一下我的这个问题吗?