软件测试 - 性能测试 (实战 - 基于场景的性能测试-博客系统)(⼯具 - JMeter )

一、 JMeter介绍

1.1 安装JMeter

下载tar包,解压即可。
这里使用的是5.5版本的
解压后,在bin目录下找到 jmeter.bat 双击
正常双击之后,会出来一个终端
如果报错,在bin目录下,打开jmeter.properties文件,找到这一行
解开注释,将false改为true

1.2 配置环境变量

把jmeter文件bin目录的位置复制进去

1.3 在cmd终端里 输入 jmeter ,即可打开工具了

关闭工具的方式:叉掉软件或者cmd终端

1.4 JMeter 工具基础配置

1.4.1 字体修改成中文 

在jmeter的bin⽬录下,修改⽂件中的内容:language=zh_CN

再次重启jmeter,就变成中文了

因为是在配置文件里修改的,之后打开就都是中文的不用每次调整了

1.4.2 字体大小(放大、缩小)

但由于这个无法在配置文件修改,所以每次打开都要自己手动调整

外观也可以自己修改


 

二、JMeter基本使⽤流程

1)启动JMeter

2)在“测试计划” 右键 下添加“线程组”

线程组:对线程进行管理

 3)在“线程组”下添加“HTTP请求”的取样器

4)填写“HTTP请求”的相关请求数据

 复制cURL

 与postman使用方法类似

点击运行 并保存

再次点击运行启动,能发现这里红色跳动了一下,到底运行成功与否并没有看到效果

 5)在“线程组”下添加“查看结果树”监听器

再次点击运行,结果树里出现了一个http请求

点击这个绿色的,可以看到取样器结果

但是这里只有一个请求,也就是模拟了一个用户

6)模拟多用户

首先将之前的请求,全部清除

再到线程组里设置线程数量,模拟多用户

点击运行,发现这里生成了10个请求的取样器结果,也就是 10次并发

三、重点组件

3.1 线程组

控制JMeter将⽤于执⾏测试的线程数,也可以把⼀个线程理解为⼀个测试⽤⼾。

当线程组里有多个请求,若http请求在性能测试运行的过程中出现了接口错误,要采取什么措施?

默认是:继续(无需修改就使用这个)

1) 线程数

线程数:⼀个线程即⼀个测试⽤⼾,设置发送的请求次数(虚拟用户数/并发数
Ramp-up时间(秒):设置性能测试运⾏时间,单位为秒( 在这个时间内完成性能测试
循环次数:
配置指定次数:控制脚本循环执⾏的次数
配置循环 永远 :( 一定要配置调度器
        ▪ 运⾏时间:脚本执⾏时间
        ▪ 延迟启动时间:脚本等待指定时间才能运⾏

2)Ramp-Up时间 

一秒之内发送10次请求,循环次数1次

就会得到10次请求结果

3)循环次数、调度器

注意:取消勾选 永远循环 之后,一定要记得在框框里写上次数,不然启动测试,会自动勾选上永远循环的

一秒内完成发送10次请求,永久循环

点击调度器之后,设置持续时间为2s

这2s内,最终发送多少次请求,我们也不知道。

因为10个请求可能0.1s就完成了,然后循环发送,直到2s结束

 通过聚合报告,能看到到底这2s内发送了多少个请求

 4)通过结果树查看报错

 4-1 请求的ip地址错误

失败:链接 8.137.19.14 这个服务器 超时

发现服务器ip填错了

在请求结果也能看到问题

 4-2 请求的路径错误 

发现报错401,ip地址没错,路径错了

通过请求头或者请求体查看到问题所在,路径写错了login1

4-3 请求成功 

通过 状态码 和 响应数据 来判断是否请求成功

这里响应码 :200 成功

响应数据data:success成功

load time 响应时间(ms)也可以帮助我们判断这个系统的性能

3.2 Http取样器

添加必需的配置:
http协议:http/https
http主机名/IP: 例如127.0.0.1
端⼝:例如80/8080/443等
        ◦ http协议端⼝号 80
        ◦ https端⼝号 443
请求⽅法
路径(⽬录+参数)
内容编码(默认的ISO国际标准,但对中⽂⽀持不友好,可以使⽤utf-8)
参数
        ◦ 参数可以拼在路径⾥,也可以卸载参数中
        ◦ POST参数要放到消息体数据中{wd:test}

 3.3  查看结果树

一般查看结果树,在自己调试的时候会用到,实际测试不会看结果树
取样器结果:统计请求相关的信息
Thread Name :线程组名称
Sample time: 发送请求时间
load time :响应时间
Response code :接⼝响应状态码
请求:HTTP请求的请求头和请求体的详细信息
响应:HTTP响应的响应头和响应体的详细信息

3.4  HTTP请求默认值

同一个系统中的接口,协议、IP、端口号是不变的,但是每次新建请求后又要重新写,特别麻烦 

配置HTTP请求默认值 

写上博客系统的协议、ip、端口号、内容编码

配置好默认请求值后,即使其他请求去掉 协议、ip、端口号,默认也会是刚才配好的值,所以也能访问。

请求默认值作用于在同一路径下的请求,如果请求里配置了的选项,就以请求中的选项作为参数;如果没有配置,就是默认配置的值。

 3.5 HTTP请求头管理器

3.5.1 获取列表时,请求头里的 user_token_header 

 至于博客列表为啥没能访问,因为还没填写请求方法和路径

配置好博客列表的路径和请求方法后,访问依然报错

响应码:401 (Unauthorized未认证)

打开新的页面,依然是401,无法正常访问

 可是正常登录之后,访问列表页就能访问了,到底是哪里出现了问题呢?

重新观察一下正常的从登录到访问列表页的过程。

成功登录之后,返回了一个data这样的数据

在浏览器的列表页 getList这个接口的请求头里,有个user_token_header,它的数值与上面登录时返回的data值 相似

是不是说明,获取列表页请求是因为少了这样一个参数

于是在发送请求时,在请求头里加上这样的参数

果然成功了

 3.5.2 jmeter 配置HTTP请求头里的参数

添加相关的数据:例如 user_token_header

然后重新运行,发送请求

发现博客列表的请求发送成功了,而且可以在请求头里看到,带上了刚才配置的HTTP请求头的参数


 

 3.5.3 作用域

jmeter里,配置好的只会作用于同级目录下。

默认情况: HTTP请求头配置后,作用于该整个线程组 

如果想作用与单个请求,就把该HTTP请求头配置放在,请求的子集

我们发现 :登录页面的请求头也有了这个参数,这其实是不必要的

所以我们需要将这个请求头只作用于博客列表页

把这个请求头的配置拖到对应的请求这里就好了,这样就只作用在这个博客列表请求了

此时再重新运行,登录页的请求头里就没有那个参数了

 3.6 JSON提取器

接⼝响应成功,通过提取返回值对应字段,可⽤于其他接⼝的参数配置

        如何提取登录接口返回值里的data数据,作为列表页接口的请求头信息?

        细心可以观察可以发现,每次登录请求,响应的数据data里的数值是在变化的,每次都不一样,而我们手动配置的token用于是固定死的,不灵活。而且,要是换一个用户登录,token就不一样了,就又需要手动配置,即使是同个用户登录,token值会过期,也不能一直用下去。

于是我们可以根据响应的数据,把需要的参数和值 提取出来

1)添加JSON提取器 

2)JSON 路径操作符

详细可以查看相关博客和资料

jsonpath :从入门到精通-CSDN博客

这篇写的蛮详细的

提取这里面的data

使用工具 JSON Path Tester ,通过输入JSON 路径操作符 ,来检查是否成功获取到了 json格式里的相关数据

输入正确,会把对应的参数值显示出来

输入错误,会有对应的提示

3)  配置 JSON提取器

将刚写好的 JSON Path(json路径) 放进 JSON Path expressions(json路径表达式)里

Names of created variables : 指的是json提取到的数据保存到这个变量里,也就是变量名

JSON Path expressions:使用json路径表达式,获取到json里数据

更改 HTTP信息头里的值

${token} 就是获取token这个json变量

 重新发送请求

这时,登录页响应的数据data,作为博客列表页请求头的参数,发送出去了

可以发现这两个数据是一致的,说明发送正确,成功了

4)作用域

同理,获取用户信息的接口,再加上一个http信息头管理器

但是运行发现还是 401

查看请求头,发现这个值不是我们预期的

发现json提取器提取的是data,而 登录页面 和 列表页面 的响应数据里,都有data

而 json 提取器是和 登录请求和列表请求 同级,所以都作用到了

最开始作用在登录请求上,将登录请求后的响应结果里的 data数据提取出来了token,作为了 列表请求 的请求头参数。

所以 登录 和 列表 的请求 都成功响应了。

但是 随后 接着作用在列表请求,把列表响应的响应结果里的 data数据 提取出来了token,覆盖掉之前的token

从而导致,新的token变了,请求失败

于是调整先后,把json提取的登录凭证放到 登录请求里,这样就只在登录里作用,出了登录页就不会改变了

又因为登录页和列表页获取的token信息一样,可以直接放在同级目录下管理

3.7 用户定义的变量

         在列表页点击不同的文章就会进入详情页,不同的详情页取决于唯一的 blogid

也就是说,blogid是会变化的,并且如果删除掉一篇文章后,这个blogid也就失效了,无法请求成功。

        于是就需要对详情页的请求参数进行设置。

由于列表页的响应数据就是所有的博客,从而可以把列表响应的blogid提取出来,作为详情页的参数值。

于是乎,使用json提取器 和 http请求头设置

但有一个问题,假设,这里有很多个页面,每个页面都要测试

拿这里的 $.data.[0].id 就要有 $.data.[1].id  、  $.data.[2].id  、$.data.[3].id 等等

添加 用户自定义的变量

 

添加编辑博客页的请求

加上相关数据

记住 json数据需要 的key 和value 需要加引号

 发现失败了

使用网页和postman再发送,对比一下请求头和请求体

发现请求头中的 content-type 不一致

于是再编辑博客页设置请求头参数

将content- type 设置为application/json

运行后,响应成功了

3.8 JSON断言

 登录之后,用json断言我们登录响应的结果

当登录成功后,返回SUCCESS,刚好匹配我们预期的SUCCESS ,断言就成功了

通过这个断言可以判断,登录是正常响应的 

对于一些总在变化的且有一定规律的数据,可以使用正则表达式来表示。

例如:用户名称、手机号、以及下面这张图的用户的 token信息

又比如说,使用JSON断言 来判断列表页userId是否为1

 或者使用正则表达式,来判断userId是否为数字(或者多个数字)

3.9 同步定制器

        JMeter同步定时器的作⽤主要在于模拟多⽤⼾并发访问的场景,确保多个线程能够同时执⾏某个操作,以达到 真正的并发效果
        当多个线程同时启动时,它们可能会在不同的时间间隔内执⾏,这样就⽆法达到真正的并发效果。同步定时器的作⽤就是将这些线程的执⾏时间同步,使它们在同⼀时间点执⾏。它可以在多个线程之间 制造⼀定的延迟,直到同时到达指定时间点,再同时执⾏后续的操作。
        此外,同步定时器可以理解为 集合点 ,当线程数量达到指定值后,再⼀起释放,可以瞬间产⽣很⼤的 压⼒。这样,可以更好地模拟真实的⽤⼾并发访问场景,提⾼测试的准确性和可靠性。
        在性能测试过程中,为了真实模拟多个⽤⼾同时进⾏操作以度量服务器的处理能⼒,可以使⽤同步定 时器来设置集合点。不过,虽然通过加⼊集合点可以约束请求同时发送,但不能确保请求同时到达服 务器,所以只能说是较真实模拟并发

例如这样的场景,在这个线程组里又5个线程,在1s内执行完成

        观察发现,启动后,各个线程陆陆续续开始了,但每个线程并不是同时进行的,有的还没开始,有的已经结束了。

 添加同步定时器

现在线程组里有5个线程,就添加并发数为 5(模拟用户的数量)

可以发现,设置同步定时器后,所有的线程都是同步一起开始的

现在线程组里有5个线程,假如我把模拟用户的数量设置为50会怎样??

模拟用户的数量 不能超过 线程组里的线程数,超过会一直等待

既然 模拟用户的数量 不能超过 线程组里的线程数,那能不能小于呢???

为什么 线程1、2、3都完成了,4和5迟迟没有完成呢??

        可以,但是 若模拟用户的数量 小于 线程组里的线程数,那最好开启循环,不然会有还未准备的线程在等其他线程。

3.10 事务控制器 

事务控制器平时用的比较少,基本上是单接口的性能测试

一个接口看做成一个事务

这里有五个事务

添加事务控制器

 可以把多个接口,放入一个事务里

例如:把登录和用户这两个接口放到一个事务里

在聚合报告可以看到这样的数据

这里的数值大部分都是毫秒为单位

最常使用参考的数据是 95%、99%请求的响应时间

3.11 csv数据文件设置

以登陆接⼝为例,当我们执⾏登陆接⼝的性能测试时,⼿动配置了⽤⼾名和密码为固定的username和 password,然⽽实际使⽤中不可能只有⼀个⽤⼾登陆。
        为了模拟更真实的登录环境,我们需要提供更多的⽤⼾username和password来实现登录操作。
添加⽅式:线程组⸺配置元件⸺CSV数据⽂件设置

在登录请求这里,之前是写死的用户名和密码

zhangsan 123456

现在使用变量${username} ${password}来代替

 使用excel表格创建csv文件,写好用户名和密码

运行之后,发现的确使用了csv文件的多个账号登录了

 3.12 HTTP Cookie管理器

        HTTP Cookie管理器像Web浏览器⼀样存储和发送Cookie。如果HTTP请求并且响应包含cookie,则 Cookie管理器会⾃动存储该cookie,并将其⽤于将来对该特定⽹站的所有请求。每个JMeter线程都有⾃⼰的"cookie存储区"。因此,正在测试使⽤cookie存储会话信息的⽹站,则每个JMeter线程都将拥有⾃⼰的会话。此类Cookie不会显⽰在Cookie管理器显⽰屏上,可以使⽤"查看结果树监听器"查看。
        缓存配置可选择standard(标准)或compatibility(兼容的),当然也可以⼿⼯添加⼀些cookie.
添加了HTTP Cookie管理器后,会⾃动存储并发送Cookie

四、Jmeter 插件管理工具

        并发测试测试中,假设期望最高并发量为10000,但是测试的时候不能一上来就直接测试10000,有可能这个就是系统的极限了,一上来就直接卡死崩溃了。

所以 并发测试都是 一点一点往上去加的

1000

2000

5000 ...慢慢加到期望的数值,也有可能在期望数值之前就已经达到极限了

普通修改就是在线程组里修改线程数量

但是这样并不能直观看到不同线程数并发时的区别和效果

4.1 Jmeter插件管理工具下载

Install :: JMeter-Plugins.org

下载后放到jmeter的lib的ext路径下

之后,jmeter工具就可以支持安装插件了

关闭jmeter然后重启

右上角有一个像蝴蝶翅膀的东西,就说明成功了

 4.2 下载 监听器插件、线程组插件

点击小蝴蝶图标,在available plugins 里面搜索 page data extractor(监听器插件)、custom thread group(线程组插件)

安装后重启

安装成功之后,就会发现多了这些工具

4.3 Stepping Thread Group 梯度压测线程组

This group will start:启动多少个线程,同线程组中的线程数
First, wait for:等待多少秒才开始压测,⼀般默认为0
Then start:⼀开始有多少个线程数,⼀般默认为0
Next,add:下⼀次增加多少个线程数
threads every:当前运⾏多⻓时间后再次启动线程,即每⼀次线程启动完成之后的的持续时间;
using ramp-up:启动线程的时间;若设置为5秒,表⽰每次启动线程都持续5秒
thenhold loadfor:线程全部启动完之后持续运⾏多⻓时间
finally,stop/threadsevery:多⻓时间释放多少个线程;若设置为5个和1秒,表⽰持续负载结束之后每1秒钟释放5个线程
例如这个

五、性能测试报告

5.1 使用命令行生成jemter性能测试报告

Jmeter -n -t 脚本⽂件 -l ⽇志⽂件 -e -o ⽬录
-n : ⽆图形化运⾏
-t : 被运⾏的脚本
-l : 将运⾏信息写⼊⽇志⽂件,后缀为 jtl 的⽇志⽂件
-e : ⽣成测试报告
-o : 指定报告输出⽬录
发现在我们指定的test文件夹下,已经生成好了测试报告的网页文件
双击index.html

 5.2 测试报告的内容

 

还有一些图表可以查看

5.3 分析性能测试报告

5.3.1 响应时间 

性能测试报告,只能发现问题,并不能解决问题,测试人员需要会使用性能测试工具进行性能测试,并分析。把测试报告给开发人员,他们来进一步解决问题。

 

在这里问题很明显的是响应时间,博客列表的平均响应时间,达到了9秒

        分析:

        1)博客列表里有很多博客,而底层我们写的是遍历完所有的博客,也就是一次全部展示完,也就是全表查询。随着博客的增加,全部遍历完的响应时间就会增大

        2)系统不稳定,有时快,有时慢。随着并发压力变大,而慢慢变慢,导致响应时间增大。

        所以,在展示的时候,可以分页展示,一次展示10个,用户往下滑动继续翻页的时候,再继续展示接下来的页面。

5.3.2 错误率(可靠性)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值