当前位置: 首页 > news >正文

Jmeter基础

1. 介绍

Jmeter 是 Apche 公司使用 Java 平台开发的一款测试工具,其主要功能如下👇:

  • 接口测试(http接口)
  • 性能测试
  • 压力测试(优势)
  • 数据库测试
  • Java程序测试

2. 元件

元件即为多个类似功能组件的容器(类似于类),组件用于实现独立的某个功能(类似于方法)

image-20240218121429794
  • 取样器:发送请求
  • 逻辑控制器:控制语句的执行顺序
  • 前置处理器:对请求参数进行预处理
  • 后置处理器:对响应结果进行提取
  • 断言:检查接口的返回结果是否与预期结果一致
  • 定时器:设置等待
  • 测试片段:封装一段代码,供其他脚本调用
  • 配置元件:测试数据的初始化配置
  • 监听器:查看Jmeter脚本的运行结果

作用域原则

  • 取样器:核心,没有作用域
  • 逻辑控制器:只对其子节点中的取样器和逻辑控制器起作用
  • 其余元件
    • 如果是某个取样器的子节点,则该元件只对其父节点起作用
    • 如果其父节点不是取样器,则其作用域是该元件父节点下的其他所有后代节点(包括子节点,子节点的子节点等)

执行顺序

  • 同一作用域下不同元件

    配置元件 --> 前置处理程序 --> 定时器 --> 取样器 --> 后置处理程序 --> 断言 --> 监听器

  • 同一作用域下相同元件

    从上到下的顺序依次执行

例子

image-20240218155318769

各组件执行顺序如下【保证 IF 控制器能正常进入的情况下】👇

定时器1 --> HTTP请求1 --> 定时器1 --> 定时器2 --> HTTP请求2 --> 定时器1 --> 定时器3 --> HTTP请求3

解释

  1. 同一作用域下,定时器优先级高于取样器,因此首先执行定时器1,再者为HTTP请求1
  2. 除去取样器与逻辑控制器外,其余元件如果其父节点不是取样器,则其作用域是该元件父节点下的其他所有后代节点。定时器1的父节点为线程组,不属于取样器,因此在后代节点发挥作用前会再次调用定时器1
  3. 进入逻辑控制器,按照其优先级顺序分别执行定时器2HTTP请求2定时器3是取样器的子节点,因此也发挥作用,最后是HTTP请求3

3. 三个重要组件

3.1 线程组

特点

  • 模拟用户,支持多用户操作
  • 多个线程组可以串行执行,也可以并行执行

分类

  • 普通线程组:编写脚本
  • setup 线程组:前置处理,初始化
  • teardown 线程组:后置处理,环境恢复等

属性

image-20240218172852934

循环次数是指每个线程的循环次数

案例分析:
使用 1 个线程组,添加 HTTP 请求(百度)

  • 配置线程数为2,循环次数为 3 时,运行观察结果
  • 配置线程数为3,循环次数为 2 时,运行观察结果,对比是否有不同

相同点:从请求数量来说,是完全相同的

不同点:场景不同

  • 线程数:代表用户数,即性能测试时的负载量(线程数为 2 比线程数为 3 对应的负载量小)
  • 循环次数:代表时间,即性能测试时的运行时间(循虾次数 3 比循环次数 2 对应的时间长)

3.2 HTTP取样器

作用:向服务器发送http及https请求

位置:选中线程组 --> 右键 --> 添加 --> 取样器 --> HTTP请求

image-20240223163755675

3.3 查看结果树

作用:查看结果

image-20240223173538372

位置:选中线程组 --> 右键 --> 添加 --> 监听器 --> 查看结果树

4. 参数化

使用参数的方式来替代脚本中的固定测试数据

实现方式:

  • 定义变量(最基础)
  • 文件定义的方式(所有测试数据都是固定的情况下)
  • 数据库的方式(灵活,业务测试常用)
  • 函数的方式(灵活,业务测试常用)

4.1 用户定义的变量

作用:定义全局变量

位置:线程组 --> 配置元件 -->用户定义的变量

image-20240223194312034 image-20240223194425119

4.2 用户参数

作用:针对同一组参数,当不同用户来访问时,可以获取到不同的值

位置:选中线程组 --> 右键 --> 添加 --> 前置处理器 --> 用户参数

  1. 添加线程数为 n(代表模拟的用户数)
  2. 添加用户参数
    • 第一列添加多个变量名
    • 后续每一列为一组用户的数据
  3. 添加 HTTP 请求,引用定义的变量名,格式:${}$
  4. 添加查看结果数

案例:向百度发送两次get请求,携带name与age参数,值分别为张三、李四,18、20

image-20240223200352975

线程组中的线程数设置为 2 模拟两个用户

image-20240223201509074

发送的两次请求URL路径如下👇

image-20240223201734748

4.3 csv数据文件设置

作用:让不同用户在多次循环时,可以取到不同的值

位置:线程组 --> 配置元件 --> CSV数据文件设置

使用方法与用户参数类似

image-20240223203421192

4.4 counter函数

作用:自动生成不重复的数据,让每个用户每次循环都能取到不同数据,且不需要提前定义

位置:菜单栏点击工具 --> 函数助手对话框

image-20240223205314514

5. 断言

检查实际的返回结果是否与预期结果保持一致

Jmeter 有自动校验机制,即自动判断响应状态码(2xx:成功,4xx/5xx:失败)

  • 响应断言:对任意格式的响应数据进行断言
  • json断言:对 json 格式的响应数据进行断言
  • 持续时间断言:对响应时间进行断言

5.1 响应断言

作用:对HTTP请求的任意格式响应结果进行断言

位置:线程组 --> HTTP请求 --> 断言 --> 响应断言

image-20240224132403287

当测试字段预期结果与实际结果不符时,在查看结果树中会出现如下提示

image-20240224132646911

5.2 JSON断言

作用:对 HTTP请求的 json 格式响应数据进行断言

位置:线程组 --> HTTP请求 --> 断言 --> JSON 断言

image-20240224134823261

5.3 持续时间断言

作用:对响应时间进行断言

位置:线程组 --> HTTP请求 --> 断言 --> 断言持续时间

image-20240224135220331

当持续时间超出最高值时,在查看结果树中会出现如下提示

image-20240224135358823

6. 关联

请求之间有依赖关系,一个请求的响应数据作为另一个的请求参数来传递

6.1 正则表达式提取器

作用:针对任意格式的响应数据进行提取

位置:线程组 --> HTTP请求 --> 后置处理器 --> 正则表达式提取器

image-20240224143412529

模板中,计数以括号为单位,$1$代表第一个括号匹配的值
匹配数字是对每个括号匹配元素的计数

案例:向哔哩哔哩发送请求,获取其title值并作为关键字访问百度

image-20240224150010408 image-20240224150027739

查看结果树结果如下

image-20240224150211085

6.2 XPath提取器

作用:针对HTML格式的响应结果数据进行提取

位置:线程组 --> HTTP请求 --> 后置处理器 --> XPath提取器

image-20240224153416061

6.3 JSON提取器

作用:针对 JSON 格式的响应结果数据进行提取

位置:线程组 --> HTTP请求 --> 后置处理器 --> JSON提取器

image-20240224155416924

6.4 Jmeter属性

需要实现跨线程组的数据传递时,可以使用 JMeter 属性,将线程组的局部属性存储为全局属性

案例:在线程 1 保存请求(http://m.nmc.cn/rest/predict/59289?_=1708762524613)返回的 json 数据中city关键字对应的值,并在线程2中用于百度搜索

image-20240224170212142

其测试计划对应如下:

image-20240224170326057

首先使用 JSON 提取器保存关键值到线程 1 中

image-20240224170450149

接着使用 setProperty 函数实现局部变量到全局变量的转换,同时在此线程组中添加 BeanShell 取样器用于执行此函数,完成变量保存

image-20240224165423888 image-20240224165752981

再次调用函数助手,生成 property 函数

image-20240224170845815

最后在线程组 2 中需要传参的地方调用函数,完成传参

image-20240224171018096

查看结果树

image-20240224171055313

7. 直连数据库

7.1 应用场景

  1. 用户请求的参数化

    例如登录时需要的用户名,可以从数据库中查询获取

  2. 用作结果的断言

    例如添加购物车下订单,检查接口返回的订单号,是否与数据库中生成的订单号一致

  3. 清理垃圾数据

    例如添加商品(商品号/编号等不能重复),再执行该脚本不能成功,需要在下次执行前删除该商品数据

  4. 准备测试数据

    例如通过数据库来准备大量性能测试数据

7.2 关键配置

将 MySQL 驱动 jar 包放入到 lib/ext 目录下,重启 JMeter

连接数据库配置

位置:线程组 --> 配置元件 --> JDBC Connection Configuration

image-20240224203456601

执行SQL语句配置

位置:线程组 --> 配置元件 --> JDBC Request

image-20240224203905387

由于查询的数据条数未知,因此实际上存储的变量名会在 Variable names 的基础上进行编号,如 Variable names 若为 var,则实际上其第一条元素变量引用名为 var_1

完成配置与语句编写,执行后通过查看结果树即可得到查询结果

image-20240224204112785

8. 逻辑控制器

8.1 IF控制器

作用:控制其下测试元素是否运行

位置:线程组 --> 逻辑控制器 --> IF控制器

image-20240225105129120 image-20240225105602447

8.2 循环控制器

作用:控制其下测试元素循环执行

位置:线程组 --> 逻辑控制器 --> 循环控制器

image-20240225105837794

8.3 ForEach控制器

作用:一般和用户自定义变量或者正则表达式提取器一起使用,读取返回结果中一系列相关的变量值。该控制器下的取样器都会被执行一次或多次,每次读取不同的变量值

位置:线程组 --> 逻辑控制器 --> ForEach控制器

image-20240225112132632

结束循环字段不填时默认遍历到最后一个

案例:引用用户自定义变量访问网站

image-20240225113124136

ForEach控制器设置如下

image-20240225113507025 image-20240225113945536 image-20240225114040144

9. 定时器

9.1 同步定时器

作用:测试抢购、秒杀或者抢红包等高并发的场景下使用

位置:线程组 --> HTTP请求 --> 同步定时器

image-20240225121211963

设置超时时间需要注意以下两点:

  • 建议设置:不设置的话,若没有达到设置的线程数会一直死等
  • 不能设置太小:等待时间后还没达到设置的线程数,会释放已到达的线程

通过监听器中的聚合报告可以查看线程发送的动态过程

9.2 常数吞吐量定时器

作用:让 JMeter 按指定的吞吐量执行,以每分钟为单位

位置:线程组 --> HTTP请求 --> 定时器 --> 常数吞吐量定时器

image-20240225145133530

QPS(Queries-per-second)即每秒查询率

9.3 固定定时器

作用:让请求间隔一定时间后再执行

位置:线程组 --> HTTP请求 --> 定时器 --> 固定定时器

image-20240225150124929

10. 测试报告

10.1 聚合报告

作用:收集性能测试结束后,系统的各项性能指标。如:响应时间、并发数、吞吐量、错误率等

位置:测试计划 --> 监听器 --> 聚合报告

image-20240225162909334
  • Label:每个请求的名称
  • 样本:各请求发出的数量
  • 平均值:平均响应时间(单位:毫秒)
  • 中位数:中位数,50% <= 时间
  • 90%百分比:90% <= 时间
  • 95%百分比:95% <= 时间
  • 99%百分比:99% <= 时间
  • 最小值:最小响应时间
  • 最大值:最大响应时间
  • 异常%:请求的错误率
  • 吞吐量:吞吐量。默认情况下表示每秒完成的请求数,一般认为它为TPS
  • 接收KB/sec:每秒接收到的千字节数
  • 发送KB/sec:每秒发送的千字节数

10.2 HTML测试报告

作用:JMeter 支持生成 HTML 测试报告,以便从测试计划中获得图表和统计信息

# 命令需在jmeter的bin目录下执行
# 存放结果在jmeter中bin目录下的report文件夹,保证此时无report目录
jmeter -n -t "测试计划.jmx" -l 测试结果.jtl -e -o ./report

11. 并发数计算

普通方法

  • 并发TPS = 总请求数/总时间
  • 只能满足最基本的要求,但是不能很好覆盖系统正常的使用情况

二八原则

  • 并发TPS = 总请求数 * 80% / (总时间 * 20%)
  • 满足系统绝大多数情况下的应用场景需要

根据业务运营数据的统计计算(通常用来做稳定性测试)

  • 并发 TPS = 有效请求数 * 80% / (有效时间 * 20%)
  • 当运营数据统计越精确时,计算出的并发TPS与实际的越接近

根据用户峰值业务操作来计算(通常用来做压力测试)

  • 并发TPS = 峰值请求数 / (峰值时间 * 系数)
  • 满足峰值请求时间段内的负载量,系数取决于项目组对于未来业务量的评估

例子

某购物商城,经过运营统计,正常一天成交额为100亿,客单价平均为300元,交易时间主要为 10:00 - 14:00,17:00 - 24:00,其中 19:00 - 20:00 的成交量最大,大约成交20亿。

现升级系统,需要进行性能测试,保证软件在上线后能稳定运行。

请计算出系统稳定性测试时的并发(负载)量,及保证系统峰值业务时的并发(负载)量。
稳定并发量: 100 E 300 × 0.8 3600 × 11 ∗ 0.2 压力并发量: 20 E 300 3600 × 1 × 系数 稳定并发量: \dfrac{\frac{100E}{300} \times 0.8}{3600\times11*0.2}\\ 压力并发量: \dfrac{\frac{20E}{300} }{3600\times1\times系数} 稳定并发量:3600×110.2300100E×0.8压力并发量:3600×1×系数30020E

12. Jmeter插件

使用第三方的扩展功能,可以使得 Jmeter 更为强大

使用插件前,首先需要安装Jmeter插件管理工具,下载地址如下所示👇:

https://jmeter-plugins.org/wiki/PluginsManager/

将下载后的 jar 包放入Jmeter的 lib/ext 目录下,接着按照此博客方法进行配置:Jmeter插件管理器打开报错解决办法

点击菜单栏“选项” --> “JMeter Plugins Manager”,若能顺利显示如下👇界面,则说明准备工作完成。

image-20240225203815158

在 Available Plugins 中添加如下四个插件,后续需要使用

image-20240225204453670

12.1 阶梯线程组

作用:阶梯加压,图形界面显示运行状态

添加方式:线程(用户) --> Concurrency Thread Group

image-20240226110905896

12.2 各种图表监听器

作用:统计各个事务每秒成功的事务个数

添加方式:线程组 --> 监听器 --> Transactions per Second

image-20240226112946612

作用:查看服务器吞吐流量(单位/字节)

添加方式:线程组 --> 监听器 --> Bytes Throughput Over Time

image-20240226113442268

作用:用来监控服务端的性能资源指标的工具,包括cpu、内存、磁盘、网络等性能数据

添加方法:线程组 --> 监听器 --> PerfMon Metrics Collector

注意:使用之前需要在服务器端安装监听服务程序并启动

  • 下载安装包 ServerAgent-2.2.3.zip,链接地址:https://github.com/undera/perfmon-agent
  • 上传到服务器上,并解压 ServerAgent-2.2.3.zip
  • 启动,如果是 Windows 运行 startAgent.bat ,如果是 Linux 运行 startAgent.sh
  • 启动这个工具后,Jmeter 的插件 PerfMon Metrics Collector 就可以收集服务端的资源使用率,并在 Jmeter 中查看了
image-20240226115442568

除此之外还要其余一些指标的监听器,此处不再一一展示

相关文章:

  • SpringMVC的文件上传与下载
  • element el-table表格内容宽度自适应,不换行,不隐藏
  • NR 2-STEP RA Absolute Timing Advance Command MAC CE的应用场景
  • 连接未来:嵌入式系统在物联网时代的应用
  • 【每日前端面经】2023-02-27
  • go - 学习笔记 -2
  • 服务器防火墙的应用技术有哪些
  • Redis 16种妙用
  • 黑马程序员——接口测试——day03——Postman断言、关联、参数化
  • 智慧公厕让社区生活更美好
  • Python实战:读取MATLAB文件数据(.mat文件)
  • windows系统使用Vscode在WSL调试golang本地进程
  • windows安装部署node.js并搭建Vue项目
  • 半小时到秒级,京东零售定时任务优化怎么做的?
  • 数据库 -neo4j的基本操作
  • JavaScript-如何实现克隆(clone)函数
  • Linux中的硬链接与软链接
  • ng6--错误信息小结(持续更新)
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • React-Native - 收藏集 - 掘金
  • ReactNativeweexDeviceOne对比
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • TypeScript实现数据结构(一)栈,队列,链表
  • 阿里研究院入选中国企业智库系统影响力榜
  • 订阅Forge Viewer所有的事件
  • 数据结构java版之冒泡排序及优化
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 详解移动APP与web APP的区别
  • 在weex里面使用chart图表
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • #{} 和 ${}区别
  • (06)金属布线——为半导体注入生命的连接
  • (二)WCF的Binding模型
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (学习日记)2024.01.09
  • (译)2019年前端性能优化清单 — 下篇
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)Unity3DUnity3D在android下调试
  • (转)关于多人操作数据的处理策略
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .axf 转化 .bin文件 的方法
  • .bat批处理出现中文乱码的情况
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET/C# 的字符串暂存池
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .NET开发人员必知的八个网站
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?
  • @Autowired多个相同类型bean装配问题
  • @EnableAsync和@Async开始异步任务支持
  • [20180224]expdp query 写法问题.txt