用JMeter对HTTP接口进行压测(一)压测脚本的书写、调试思路

news2024/11/18 23:34:28

文章目录

  • 安装JMeter和Groovy
    • 为什么选择Groovy?
  • 压测需求以及思路
  • 准备JMeter脚本以及脚本正确性验证
    • 使用Test Script Recorder来获取整条业务线上涉及的接口
      • 为什么使用Test Script Recorder?
    • 配置Test Script Recorder
    • 对接口进行动态化处理
      • 处理全局变量以及命名各接口
      • 接口请求前、请求后的脚本处理
        • 使用JSR233 PreProcessor读取商品ID
        • 请求接口
        • 使用Regular Expression Extractor Post-Processors来处理接口响应并为下一个接口设置变量
        • 使用Debug Sampler或Debug PostProcessor来调试脚本
        • 继续下一个接口
        • 在提交表单项时存在多个值的动态处理
  • 撤销JMeter的某些改动
  • 结语

安装JMeter和Groovy

Mac OS下使用Homebrew安装

brew install jmeter
brew install groovy

安装完毕之后,确保jmeter和groovy没问题

直接启动JMeter

jmeter

查看groovy版本

groovy -v

为什么选择Groovy?

在JMeter中使用脚本语言有BeanShell和Groovy,因为Groovy和Java更相近,所以选择Groovy。虽然以前没接触过Groovy,但是靠着IDE和官方文档、Google上手还算顺利。

压测需求以及思路

因为是需要对整条业务流程进行压测,所以各个接口之间的请求、响应需要相互依赖,做起来有点像自动化测试的流程,只不过自动化测试专注于验证测试流程结果是否准确,而这里的压测专注于某些接口是否有问题。

由于我不属于自动化测试团队,所以在我接到这个需求的时候,第一个想法就是如何准备测试数据

因为压测的是用户购买的流程,但是在用户购买之前,商家需要创建商品、根据不同的业务再给商品设置一些特殊的属性,例如商品显示设置、购买限制、折扣等。这些其实就是准备数据了。

毕竟压测还是想做成自动化的,如果做成自动化的话,那么准备数据的脚本也要写,但是这一部分其实是和自动化测试重复了。经过考虑之后,决定做成半自动化。也就是准备数据来自于自动化测试,先运行自动化测试生成基础准备数据,在基础准备数据之上,再手动做一些配置,例如给商品加很多库存等。因为我们的自动化测试对于商品不会有很多库存,而压力测试必须运行在很多库存的前提下,所以这一步通过手动配置,最后再运行压力测试。大概思路就是这样,虽然不是尽善尽美,但是能基本保证工作重心在压力测试的脚本准备以及测试上,而不是准备数据上。

准备JMeter脚本以及脚本正确性验证

由于整条业务线涉及到N个接口,所以我这里只拿几个接口来举例子,每个接口的配置思路以及调试方式基本类似。

使用Test Script Recorder来获取整条业务线上涉及的接口

为什么使用Test Script Recorder?

不知道Test Script Recorder的同学,建议先去读一遍官方文档。一句话概括就是,它会把你在页面上各种点点点的动作设计到的请求都记录下来,生成一个集合。

现实情况可能是这样:

  1. 开发团队没有接口管理工具(或者即使有),但是当前测试的这条业务线涉及的都有哪些接口,写压测脚本的人不一定很清楚。即写压测的人和开发的人不是一拨人。这种情况下,不太可能花太多时间再去了解其业务、接口传参、接口返回等等。
  2. 整体业务线接口多、复杂,各种情况都有(这在现实中很常见),而我们要测的这条线的某种场景,可能并不需要传某些参数或者处理某些响应,这样我们也不需要花太多时间去搞清楚到底什么该传什么。
  3. 方便,不需要自己一个接口一个接口的去建相关的HTTP Request Sampler,只需要进行一些参数动态处理即可。大大减少了我们的工作量。

我们只需要使用Test Script Recorder,像功能测试一样,按照我们要测试的流程,一路在页面上点下来,正常完成业务流程即可,就可以拿到,该测试流程上的所有请求接口了。

配置Test Script Recorder

直接参考JMeter官方Test Script Recorder一节即可。

注意:浏览器要使用官方文档中提到的Iceweasel/Firefox,我一开始也看到了文档,但是天真的以为是个浏览器就行,在尝试了Google和Edge之后无果后,乖乖地下载了一个Firefox浏览器。

对接口进行动态化处理

到这一步,你本地应该已经成功运行了Test Script Recorder并拿到了相关接口集合,如果没有的话,建议阅读上面提到的官方文档,确保拿到接口集合之后再阅读这部分。

处理全局变量以及命名各接口

对于每个接口都会用到的scheme、host、port、contextPath,放在User Defined Variables中,在这里插入图片描述
并在HTTP Request Defaults中引用,在这里插入图片描述
对于每个接口,最好重命名每个Http Request Sampler使其能体现出该Sampler对应的功能,这样做不仅见名知义,对于以后更复杂的压力测试,我们可能会使用多个Test Fragment来完成,也有助于以后我们拆分或重构压力测试脚本。不会因为各种奇葩命名而去花费时间再去搞清楚该脚本到底是干嘛用的。

接口请求前、请求后的脚本处理

每个接口的请求数据都是动态的,我们使用Test Script Recorder得到的接口集合里面的数据是静态的,这一步我们就是要把数据变成动态的。完成这一工作的是Pre Processors和Post-Processors。

我们前面说过,压力测试的基础数据来自于自动化测试,好在自动化测试团队将测试过程中生成的关键信息,例如商家ID、商品ID写入某个文件, 所以在请求接口之前我们需要读取该文件拿到商品ID列表,并随机获得一个商品ID

使用JSR233 PreProcessor读取商品ID

在这里插入图片描述
在显示商品接口请求之前,使用Groovy读取文件来随机获得商品ID和后续用来购买的邮件地址,并通过vars.put将其放到对应的变量中去以便后续可以读取。
关于vars支持的方法以及用法请参考JMeter官方文档最佳实践一节以及用户手册中的Function一节

请求接口

在这里插入图片描述
这里通过${itemId}引用刚刚在PrePocessor中设置的值

使用Regular Expression Extractor Post-Processors来处理接口响应并为下一个接口设置变量

由于我们这里的业务流程是MVC,而不是REST,所以返回的是个HTML页面,所以通过正则表达式后置处理器来获取页面中的元素在这里插入图片描述
这里对要获取的页面元素使用正则表达式的捕获组,也就是要用(),$1$代表第一个捕获组,以此类推。

Match No. (0 for Random) Indicates which match to use. The regular expression may match multiple times

这里会把正则表达式的结果赋值给onSale,和vars.put一样,以便后续接口可以引用

使用Debug Sampler或Debug PostProcessor来调试脚本

在对整条业务线的接口进行动态化处理的时候,我建议是:

  • 一个接口一个接口来,即改完一个接口,验证一个,没问题再继续下一个。
  • 如果是中间的接口,则是该接口没问题之后,还要和前面已验证的接口一起再验证一遍,确保接口本身动态化没问题,确保整条业务线到该接口处是正确的。
  • 在修改接口的过程中,将在该接口后面的接口先暂时Disable掉。

验证脚本 > Thread Group 右键> Validate
如果有问题了,例如没参数是空、或者请求失败等,我们需要知道,是否正确地读取了数据和正确地处理了响应数据。这时我们就需要知道,在整个脚本运行过程中,那些动态参数到底是什么?

Debug Sampler和Debug PostProcessor二者作用类似,都是将脚本运行中的参数打印出来,我一般使用Debug Sampler,放在最后面,如上面的几张截图一样。

继续下一个接口

在这里插入图片描述
这里使用If Controller来判断上一个接口响应设置的onSale是否不为空,如果不为空,则进入该controller的里面的接口。这里的接口动态化和验证和上面的类似 ,按照上述原则,这个接口验证没问题了,就可以下一个,下一个没问题,再下一个,直到整条业务线接口都覆盖到。不再赘述。

在提交表单项时存在多个值的动态处理

如果表单中每一项的HTML元素只对应一项,那么使用上面的流程没什么问题。有时候,我们一个元素可能会提交多项,正常的HTML表单提交上来的是

itme_id_1: 1
item_id_2: 2
item_id_3: 3

这种,如何处理这种情况的呢?举个例子,在Pre Processor中使用如下脚本即可

def idPrefix = "item_id_"
for(i in 1..30) {
	var key = idPrefix + i
	def value = vars.get(key)
	if(value){
		sampler.addArgument("item_ids", value)
	} else {
		break
	}
}

有关该问题可参考stackoverflow更详细的回答

撤销JMeter的某些改动

一般在写脚本的时候,保存之前 Command + Z就可以撤销,但是保存之后就撤销不了了。平时没什么问题,但是有些极特殊情况下,在保存之后想要撤销怎么办呢?

我在写脚本期间,由于JMeter不能开多个窗口,导致我有时候会频繁切换jmx文件,有一次把整体业务线的压力测试接口都已调整好了,但是我此时在JMeter中又使用Test Script Recorder中玩了一遍其他流程,然后保存了…当我反应过来之后我直接傻了,相当于之前所有的工作白做了…慌得要死…

经过调查,幸好JMeter有backup机制,默认最大备份文件是10个,文件路径是JMeter安装路径下的backups目录。不过这些都可以修改。也算是虚惊一场了。

结语

本博文没有对JMeter中的各个组件及其概念做过多介绍,我认为,这些基础的东西看看官方文档,自己多配置几个脚本就基本知道这些组件到底是干嘛的了,官方文档已经是最精华的教学文档了,我就不必在这里再次赘述了。

希望想要学习JMeter的同学,多读官方文档,遇到概念不清楚、配置不清楚的问题按图索骥即可。刚上手的同学建议多读FAQ以及Best Practices部分。

下一篇将介绍如何搭配Jenkins Job来实现半自动化压力测试,以及使用Grafana可视化压测结果,以及使用其他工具来分析压测过程中是否存在性能瓶颈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1062710.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2. 资源管理

2. 资源管理 文章目录 2. 资源管理2.1 资源管理介绍2.2 YAML语言介绍2.3 资源管理方式2.2.1 命令式对象管理2.2.2 命令式对象配置2.2.3 声明式对象配置 2.4. 模拟使用普通用户来操作 2.1 资源管理介绍 在kubernetes中,所有的内容都抽象为资源,用户需要通…

二十九、【进阶】MySQL索引的概述和索引查询

1、索引概述 2、 普通查询和索引查询 (1)基础演示 无索引查询:在查询信息时,比如查询年龄age45的员工,系统会遍历字段为age的列,在找到age45的员工后,依旧会向下扫描,直到表末&…

如何使用 Dijkstra 算法找到从源到所有顶点的最短路径--附C++/Java源码

给定一个图和图中的源顶点,找到从源到给定图中所有顶点的最短路径。 例子: 输入: src = 0,图形如下图所示。 输出: 0 4 12 19 21 11 9 8 14解释:从 0 到 1 的距离 = 4。 从 0 到 2 的最小距离 = 12。0->1->2 从 0 到 3 的最小距离 = 19。0 ->1-

Python基础语法(3)

目录 一、函数 1.1 函数是什么 1.2 函数语法格式 1.3 函数参数 1.4 函数返回值 a. 一个函数中可以有多个 return 语句 b. 执行到 return 语句,函数就会立即执行结束,回到调用位置 c. 一个函数是可以一次返回多个返回值的。使用 , 来分割多个返回值…

Jmeter基础篇

1.性能测试指标 【虚拟用户数】:线程用户 【并发数】:指在某一时间,一定数量的虚拟用户同时对系统的某个功能进行交互,一般通过集合点实现 【事务】:事务代表一个完整的功能,一个接口可以是事务,多个接口…

MyBatisPlus(十一)包含查询:in

说明 包含查询&#xff0c;对应SQL语句中的 in 语句&#xff0c;查询参数包含在入参列表之内的数据。 in Testvoid inNonEmptyList() {// 非空列表&#xff0c;作为参数List<Integer> ages Stream.of(18, 20, 22).collect(Collectors.toList());in(ages);}Testvoid in…

【C语言】转圈报数问题(三种方法--指针,数组)

题目&#xff1a;有n个人围成一圈&#xff0c;顺序排号。从第一个人开始报数&#xff08;从1到3报数&#xff09;&#xff0c;凡报到3的人退出圈子&#xff0c;问最后留下的是原来第几号的那位。 方法一&#xff1a; #include <stdio.h> #define N 10int main() {int …

systemverilog function的一点小case

关于function的应用无论是在systemverilog还是verilog中都有很广泛的应用&#xff0c;但是一直有一个模糊的概念困扰着我&#xff0c;今天刚好有时间来搞清楚并记录下来。 关于fucntion的返回值的问题&#xff1a; function integer clog2( input logic[255:0] value);for(cl…

实验三十五、LM117 稳压电源的设计

一、题目 利用 LM117 设计一个稳压电路&#xff0c;要求输出电压的调节范围为 5 ∼ 20 V 5\sim20\,\textrm V 5∼20V&#xff0c;最大负载电流为 400 mA 400\,\textrm{mA} 400mA。利用 Multisim 对所设计电路进行仿真&#xff0c;并测试所有性能指标。 二、仿真电路 仿真电…

安装NodeJS并使用yarn下载前端依赖

文章目录 1、安装NodeJS1.1 下载NodeJS安装包1.2 解压并配置NodeJS1.3 验证是否安装成功2、使用yarn下载前端依赖2.1 安装yarn2.2 使用yarn下载前端依赖参考目标:在Windows下安装新版NodeJS,并使用yarn下载前端依赖,实现运行前端项目。 1、安装NodeJS 1.1 下载NodeJS安装包…

Vue中实现自定义编辑邮件发送到指定邮箱(纯前端实现)

formspree里面注册账号 注册完成后进入后台新建项目并且新建表单 这一步完成之后你将得到一个地址 最后就是在项目中请求这个地址 关键代码如下&#xff1a; submitForm() {this.fullscreenLoading true;this.$axios({method: "post",url: "https://xxxxxxx…

【python海洋专题十一】colormap调色

【python海洋专题十一】colormap调色 上期内容 本期内容 图像的函数包调用&#xff01; Part01. 自带颜色条Colormap 调用方法&#xff1a; cmap3plt.get_cmap(ocean)查询方法&#xff01; Part02. seaborn函数包 01&#xff1a;sns.cubehelix_palette cmap5 sns.cu…

【MySQL】错误1166 Incorrect column name

错误1166 Incorrect column name 是指字段名里有空格 Incorrect column name ‘name’ 图中报错的原因是name字段中有空格 删除空格即可

基于SpringBoot的视频网站系统

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 视频分享管理 视频排名管理 交流论坛管理 留言板管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 使用旧方法对视频信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运…

ParagonNTFSforMac_15.5.102中文版最受欢迎的NTFS硬盘格式读取工具

Paragon NTFS for Mac是一款可以为您轻松解决Mac平台上不能识别Windows通用的NTFS文件难题&#xff0c;这是一款强大的Mac读写工具&#xff0c;相信在很多时候&#xff0c;Mac用户需要对NTFS文件的移动硬盘进行写入&#xff0c;但是macOS系统默认是不让写入的&#xff0c;使用小…

妙不可言的Python之旅----(二)

Python基础语法 什么是字面量 字面量&#xff1a;在代码中&#xff0c;被写下来的的固定的值&#xff0c;称之为字面量 常用的值类型 类型 描述 说明 数字&#xff08;Number&#xff09; 支持 • 整数&#xff08;int&#xff09; • 浮点数&#xff08;float&#xff…

C++基础知识(二) -- 函数重载

自然语言中&#xff0c;一个词可以有多重含义&#xff0c;人们可以通过上下文来判断该词真实的含义&#xff0c;即该词被重载了。 比如&#xff1a;以前有一个笑话&#xff0c;国有两个体育项目大家根本不用看&#xff0c;也不用担心。一个是乒乓球&#xff0c;一个是男足。前者…

如何禁用Windows 10快速启动(以及为什么要这样做)

如果您不想启用Windows 10快速启动&#xff0c;则可以相对轻松地禁用它。 快速启动是一项功能&#xff0c;首先在 Windows 8 中作为快速启动实现&#xff0c;并延续到 Windows 10&#xff0c;让您的 PC 更快地启动&#xff0c;因此得名。虽然这个方便的功能可以通过将操作系统…

Qt model/view 理解01

在 Qt 中对数据处理主要有两种方式&#xff1a;1&#xff09;直接对包含数据的的数据项 item 进行操作&#xff0c;这种方法简单、易操作&#xff0c;现实方式单一的缺点&#xff0c;特别是对于大数据或在不同位置重复出现的数据必须依次对其进行操作&#xff0c;如果现实方式改…

了解基于Elasticsearch 的站内搜索,及其替代方案

对于一家公司而言&#xff0c;数据量越来越多&#xff0c;如果快速去查找这些信息是一个很难的问题&#xff0c;在计算机领域有一个专门的领域IR&#xff08;Information Retrival&#xff09;研究如何获取信息&#xff0c;做信息检索。在国内的如百度这样的搜索引擎也属于这个…