一篇文章带你掌握性能测试工具——Jmeter

发布时间 2023-12-11 23:53:00作者: 秋落雨微凉

一篇文章带你掌握性能测试工具——Jmeter

在目前的中大型企业中,仅仅进行功能测试已经不足以满足企业的需求,在重大客户基数下性能测试将会直接影响到用户体验

所以在这篇文章中我们将会学习性能测试的相关知识以及常用工具Jmeter

我们将会从以下角度进行介绍:

  • 性能测试基础信息
  • 性能测试工具介绍

性能测试基础信息

首先我们需要去系统的了解一下性能测试的相关信息

性能测试简述

首先我们需要了解我们为什么需要学习性能测试:

  • 在目前企业里功能测试是最基本的需求,但随着用户量的增加,产品的品质也需要逐渐优化
  • 性能测试主要是针对产品的执行速率,执行占用资源,并发度,最大可承受执行次数等多方面进行测试并判断是否满足产品需求

接下来我们需要理解性能主要针对什么:

  • 性能测试主要针对两方面进行评估
  • 时间层面:用户执行该操作最后效果展现所消耗的时间
  • 资源层面:用户执行该操作对自身计算机所占用CPU等资源的消耗比率

那么性能测试就是在多种情况下对性能情况进行测试得出结果:

  • 使用自动化工具,模拟不同场景下,对软件各项性能指标进行测试和评估的过程

最后我们简单讲一下性能测试的目的:

  • 评估当前系统能力
  • 寻找性能瓶颈,优化性能
  • 评估软件是否满足未来需求,是否需要优化

性能测试对比

我们在之前的文章中已经学习了功能测试,那么我们简单给出两者的区别:

# 功能测试
# 目的:主要为了验证系统的功能需求规格是否满足产品需求
# 正向功能测试:采用完整正确的测试用例进行测试,判断是否满足产品需求
# 逆向功能测试:采用不完整或部分错误或错误的测试用例进行测试,判断是否满足产品需求

# 性能测试
# 目的:主要为了判断产品是否满足其业务需求场景
# 时间性能测试:采用业务需求场景下的测试用例获取最终时间结果,判断是否满足产品需求
# 资源性能测试:采用业务需求场景下的测试用例获取计算机资源占比,判断是否满足产品需求

我们还需要知道其两者之间的先后顺序关系:

  • 在前后端提测之后,我们首先需要进行功能测试并回归完完全功能之后,判断该产品无任何问题后再进行性能测试
  • 在完成功能测试和性能测试后,两者自动化的书写无先后顺序关系

性能测试分类

我们下面来介绍性能测试的多种测试方式

基准测试

首先我们需要介绍基准测试:

  • 狭义:基准测试其实就是单用户测试
  • 广义:基准测试是采用单用户测试在某一固定场景下进行测试并得到具体数据,以该数据作为基准和后续测试数据进行对比

我们给出一个简单实例来说明基准测试:

  • 我们在最开始采用一种情况进行测试并得到结果进行记录,后续我们采用其他方式进行测试并与基准测试结果进行对比

  • 基准测试:项目1.0版本,测试机配置(8G+16G),单用户查询一万条数据采用3.0s

  • 后续测试:项目1.0版本,测试机配置(8G+32G),单用户查询一万条数据采用2.0s

  • 后续测试:项目1.1版本,测试机配置(8G+16G),单用户查询一万条数据采用2.5s

那么基准测试的用途也很明显:

  • 基准测试从不会单独出现,它需要与其他数据比较才有意义
  • 基准测试采用单用户测试,主要是为了给后续多用户测试综合测试场景提供参考意义
  • 基准测试采用测试机测试,主要是为了给后续不同配置测试机测试综合测试场景提供参考意义

负载测试

我们同样首先来介绍负载测试的意义:

  • 通过逐步增加系统负载,确定满足系统性能指标情况下(响应时间或CPU占用率),找到该系统的最大承受量

我们给出一个简单实例来说明负载测试:

  • 我们首先会从产品那里得到一个客户性能需求,例如该电梯从1楼运输到5楼的运行时间控制在15s内
  • 那么我们就需要采用不同重量进行测试,判断是否满足客户需求并将该负载结果告诉产品
  • 我们会从下述case中选择最大的满足性能需求的重量作为负载测试的最终结果
  • case1:100KG物品在电梯中从1楼运输到5楼的运行时间是10s
  • case2:500KG物品在电梯中从1楼运输到5楼的运行时间是10s
  • case3:700KG物品在电梯中从1楼运输到5楼的运行时间是14s
  • case4:900KG物品在电梯中从1楼运输到5楼的运行时间是17s

针对负载测试我们还需要知道这些内容:

  • 系统对外宣称的一般是最大负载量
  • 负载测试的测试时间一般为1-2小时
  • 通过负载测试可以确定系统的最大负载量和极限负载量

负载测试的用途主要针对客户需求:

  • 系统最大负载量达到客户需求时,系统才能正式上线使用

稳定测试

我们首先给出稳定性测试的概念:

  • 稳定性测试主要是针对产品在稳定运行(正常业务负载下)的情况下进行长时间测试,并保证产品满足线上业务需求

我们现实中其实存在很多案例:

  • 因为不同业务存在不同业务场景,所以稳定性测试的测试时间是不同的
  • 例如12306铁路抢票软件,每天的0点到6点之间是不允许抢票的,那么我们只需要测试在一天情况下能否满足业务需求
  • 例如淘宝京东购物软件,每天无时无刻都可以进行购物,那么我们测试时长就需要稍微拉长一些来判断能否满足业务需求

负载测试的用途主要针对产品持久性:

  • 系统在用户要求的业务负载下达到规定的执行时间时,系统才能正式上线使用

压力测试

我们首先给出压力测试的概念:

  • 压力测试主要针对在高压情况下,查看系统是否存在功能隐患,判断是否是否良好的容错能力和可恢复能力

针对压力测试主要分为两方面的压力测试:

  • 系统在持续高压情况下的稳定性测试
  • 系统在超高压情况下崩溃后的恢复能力测试

我们分别给出两个案例:

# 持续高压下压力测试
# 例如B站中某个视频爆火,在一段时间内,该视频的点击率一直上升,一直调用get接口
# 那么我们就需要去测试该接口在高负荷情况下(超过正常调用频率)在一段时间内(一天或三天)是否能够正常调用且无错误

# 超高压情况下恢复测试
# 例如某个功能爆火,导致该功能的点击量/接口调用率突然提升超过预期,导致该接口/数据库信息报错
# 那么我们就需要测试在该功能崩溃情况下,是否能在较短时间内恢复该功能的正常运行/接口调用无异常

并发测试

我们同样给出并发测试的概念:

  • 并发测试是在极短的时间内,发送多个请求,判断是否出现资源争夺导致的异常情况

我们在日常生活中可以见到很多案例:

  • 双十一定时抢券活动
  • 春节火车票抢购时间

但是我们需要注意到的是并发测试和负载测试虽然都是测试资源消耗或者说是资源的最大承受量,但两者是不同的:

  • 负载测试:是指一段时间内,在高负载的情况对于资源的消耗,是否会存在资源耗尽问题
  • 并发测试:是指在极短时间内,判断是否会出现由于资源互相抢夺而导致功能无法实现问题

其实并发测试的主要测试点更像是我们操作系统中出现的死锁情况:

  • 假设我们的资源A存在10个,资源B存在10个
  • 同时存在20个线程都需要资源A和资源B,同时启动导致10个线程得到资源A,10个线程得到资源B
  • 但两者都无法得到剩余的线程,从而出现资源死锁问题,导致资源无法释放,功能无法实现从而出现并发问题

性能测试指标

我们在进行性能测试时,当然不能只根据我们的感觉来判断该性能是否符合标准,因此就出现指标这一概念

响应时间

首先我们来介绍响应时间:

  • 狭义:用户进行操作后,得到最后结果之间所消耗的时间
  • 广义:主要包含浏览器传输时间,服务器处理时间,服务器传输时间,数据库处理时间等多时间汇总所得到的结果

我们可以简单给出一张图片进行解释:

我们的响应时间通常是我们进行性能测试最直接的判断结果:

  • 例如我们查询一万条数据时所需要得到的响应时间在3s之内

但我们还需要注意一点:

  • 我们所获取的响应时间并不能是单次运行所得到的时间
  • 而是在多次运行下,所得到的所有运行时间的平均值(Jmeter会有一个字段存储平均响应时间)

吞吐量

我们来简单介绍一下吞吐量:

  • 吞吐量指单位时间内处理客户端的请求数量,可以直接体现出系统的性能承载能力

吞吐量主要分为两种:

  • TPS每秒事务数

  • QPS每秒查询数

我们首先来介绍TPS:

  • 即控制服务器每秒处理的事务请求的数量
  • 该计算仅仅针对事务的数量进行计算,一次事务(一次点击)可能会出现1个或多个请求,而这些请求都被划分为一次事务

我们采用一张图片解释:

我们再来介绍QPS:

  • 即控制服务器每秒处理的指定请求的数量
  • 该计算是指针对某单一接口请求,去统计该单位时间内所处理的请求个数

我们同样采用一张图片解释:

资源利用率

我们来简单介绍一下资源利用率:

  • 即计算机内各种资源的使用情况
  • 通常是一个比率值,采用当前使用资源数/计算机全部资源数来获取

我们常见的一些计算机资源包括有:

  • CPU使用率
  • 显卡使用率
  • 内存使用率
  • 磁盘IO效率
  • 网络传输率

性能测试流程

首先我们直接给出一张性能测试流程图:

需求分析

首先我们来讲解性能测试需求分析:

  • 所有测试的需求分析的过程都是相同的,由产品给出具体指标,由我们进行解析梳理

我们通常将性能测试需求分析划分为四步:

# 1.明确被测系统
# 我们首先需要了解我们所测试的系统的业务功能和技术架构
# 我们需要去了解我们所测试的系统的常用模块,并了解其执行步骤

# 2.明确测试内容
# 在产品给出需求的情况下,我们直接去测试产品需求点即可
# 若产品未给出需求,那么我们主要针对用户使用最频繁的部分进行测试或者针对性能过低的部分进行测试优化

# 3.明确测试策略
# 该测试策略就是我们前面所提到的测试分类方法
# 该测试策略并非需要全部执行,我们需要针对不同情况采用不同测试策略进行测试

# 4.明确测试指标
# 同样,我们以产品的需求为主,如果存在需求,则满足需求即可
# 若不存在需求,我们可以参考其他软件或之前版本的测试数据进行判断其指标

测试计划

测试计划其实主要依照公司主管所制定的计划:

  • 所测内容:依据项目背景,给出测试目的及测试范围即可
  • 所测人员:由主管进行分配各个人员的分工以及完成时间等信息
  • 所测方法:测试方法可以由主管指定,也可以由各个人员进行判断

测试用例

我们给出一张测试用例的常用模板图即可:

测试执行

我们的性能测试通常通过工具进行测试:

  • 由于性能测试需要长时间点击或频繁点击,人工无法实现
  • 我们通常通过参数化和脚本等,然后结合测试工具Jmeter或其他性能测试工具等去结合执行

我们的性能测试执行大概划分为四阶段:

# 1.建立测试环境
# 搭建性能测试环境,包括硬件环境,软件环境,网络环境

# 2.编写测试脚本
# 按照性能测试需求用例,使用性能测试工具书写测试脚本

# 3.性能测试监控
# 一般我们所使用的脚本工具都会存在性能测试监控窗口,我们只需要查看数据是否存在问题即可

# 4.执行测试脚本
# 设置性能运行场景,执行性能测试,收集测试结果并与指标进行对比

测试分析

我们在执行测试用例之后会获取到其性能测试结果,我们只需要对比即可:

  • 针对不满足产品需求的性能测试结果,我们需要要求后端对其进行优化,并在优化后回归测试

测试报告

我们在测试结束之后通常需要去书写测试报告,主要是为了我们后续测试作为对照,主要包含以下内容:

  • 测试流程记录
  • 测试风险评估
  • 测试结果记录
  • 测试分析记录
  • 测试总结改进

性能测试工具介绍

接下来我们开始正式介绍Jmeter工具的使用

Jmeter性能比较

其实除了Jmeter之外,我们还有很多性能测试工具,其中之前比较出名的就是Loadrunner,我们这里简单介绍一下两者的区别:

# 首先我们来简单说一下Loadrunner
# Loadrunner实际上算是一款很知名的性能测试工具
# Loadrunner的主要特点是:高收费,占用内存较大,功能全面无阉割,同时可模拟上万人同步操作

# 而Jmeter其实就是针对Loadrunner所做出来的阉割版性能测试工具
# 但是由于Jmeter的免费且开源使得它在如今社会满足企业需求且可以由我们自己插入第三方插件
# Jmeter的主要特点是:免费且开源,占用内存极小,基本满足企业需求,同时可模拟千人同步操作,可以手动导入第三方实现企业需求

# 且两者都包容多协议,像我们常用的Http,Https,FTP等协议,两者都可以使用
# 且两者都存在监听件,我们所做的性能操作都会直接体现在监听件中,不需要我们手动记录

Jmeter下载安装

Jmeter的下载非常简单,我们只需要到官网下载对应压缩包即可:Apache JMeter - Download Apache JMeter

我们将其压缩到对应文件夹即可,注意需要是全英文文件夹,下面我们使用一张图来介绍各文件内容:

如果我们希望快速打开Jmeter,我们通常会将该文件的bin目录放入我们的环境变量,那么我们仅需要使用一行简单命令就开启服务:

最后我们给出一下Jmeter的一个页面展示:

这里我们所看到的是英文界面,当然我们可以将其变为中文界面,我只需要进入bin目录的Jmeter.properties文件修改:

最后我们给出一个小提示,因为我的电脑存在这个问题,所以记录下来:

# 如果电脑是高刷新率,像我的电脑是240HZ刷新,就会导致Jmeter的GUI界面出现重叠问题
# 我们只需要在Jmeter.bat脚本中的第一行,加入这行代码即可
set JVM_ARGS=-Dsun.java2d.d3d=false

Jmeter元件介绍

我们首先给出一张Jmeter工具的相关元件图,我们会在下面进行解释:

下面我们依次来介绍上述元件的作用:

# 取样器
# 取样器就是用来发送请求的元件,我们在页面上点击按钮其实就是发送请求,这里就是模拟发送请求

# 逻辑控制器
# 逻辑控制器就是控制我们的元件是否执行,包含我们常用的if,while,foreach等

# 前置处理器
# 前置处理器是对我们的请求参数在执行前进行处理

# 后置处理器
# 后置处理器是对我们请求后所返回的响应进行处理

# 断言
# Python中常用的判断结果是否符合预期的功能

# 定时器
# 定时器主要用来控制我们多久后执行该取样器(发送请求)

# 配置元件
# 配置元件内的元件都是用于进行初始化的东西

# 监听器
# 监听器主要是用来获取我们使用取样器发送请求后的响应数据相关信息

接下来我们需要知道元件的作用范围都在哪里:

# Ø取样器:核心,没有作用域

# Ø逻辑控制器:只对其子节点中的取样器和逻辑控制器起作用

# Ø其他元件:
# •如果是某个取样器的子节点,则该元件只对其父节点起作用
# •如果其父节点不是取样器,则其作用域是该元件父节点下的其他所有后代节点(包括子节点,子节点的子节点等)

我们还需要注意其执行顺序:

# 在同一个作用域(目录/级别/缩进)的不同元件的执行顺序:
# 配置元件 - 前置处理程序 - 定时器 - 取样器 - 后置处理程序 - 断言 - 监听器

# 在同一个作用域(目录/级别/缩进)的相同元件的执行顺序:
# 从上到下的顺序依次执行

我们给出一张图,并给出它的执行顺序,大家可以明白其作用范围:

Jmeter案例展示

首先我们给出一个最简单的案例进行展示:

# 步骤

# 1.启动Jmeter

# 2.在“测试计划”下添加线程组

# 3.在“线程组”下添加“http请求”取样器

# 4.填写“http请求”取样器信息

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

# 6.点击启动按钮,并查看结果

我们这里首先给出http请求的界面展示,后续我们会详细介绍:

然后我们这里直接启动,给出查看结果树的执行界面展示:

Jmeter线程介绍

在了解其元组具体信息之前,我们首先需要了解一下线程组:

# 线程组一共只有三种,我们右键测试计划就可以创建线程组,这里不给图片展示了

# 1.线程组
# 控制Jmeter用于执行测试的一组用户,用于执行测试用例,可以有1个或者多个(并行/串行),后续我们会给出具体参数信息设置

# 2.Setup线程组
# 预测试操作,所有脚本之前执行
# 类似于Pytest里面的Setup方法

# 3.Teardown线程组
# 测试后操作,所有脚本之后执行
# 类似于Pytest里面的Teardown方法

我们给出线程组的展示图并说明其具体使用参数信息:

而最后我们在给出一个小贴士,是关于线程组的并行或串行启动的开关按钮:

Jmeter交互介绍

我们直接给出Jmeter请求的一张展示图,并在该展示图上进行介绍:

除了这些请求之外,我们在请求时,还需要传递参数信息:

  • 如果是get请求,我们可以直接在路径后以?key1=value1&key2=value2的形式进行传递
  • 其他请求类型,我们通常在下方的参数栏进行传递,也可以选择消息体数据采用JSON或其他格式传递,如果传递文件可以选择第三种

我们给出一张展示图:

我们顺便给出一张查看结果树的请求和响应展示图:

Jmeter参数处理

我们在之前的自动化测试中也学习到了参数化,现在我们来学习Jmeter的参数化设置:

  • 参数化的本质就是实现测试数据与测试方法的分离
  • 参数化主要使用不同的测试数据,调用相同的测试方法进行测试

全局变量

我们首先学习Jmeter参数化最基本的全局变量:

  • 用户定义的变量 —— 全局变量

首先我们进行一些全局变量信息的讲解:

# 如何定义?
# 我们可以在线程组下,创建配置元件的用户定义的变量

# 具体作用?
# 定义一些全局变量方便我们频繁使用,例如我们频繁使用某些字段或某些数据,我们就可以定义为全局变量进行使用

# 如何使用?
# 我们只需要在需要导入的地方采用${变量名}就可以使用

我们直接给出全局变量定义的界面:

我们再给出一张使用图:

用户参数

同样我们首先给出用户参数的相关概念:

  • 用户参数 —— 为每个用户分配不同的参数值

我们先来进行简单介绍:

# 如何定义?
# 我们可以在线程组下,创建前置处理器的用户参数

# 具体作用?
# 针对一组参数,当不同用户使用时,会获取不同的数据

# 如何使用?
# 我们只需要在需要导入的地方采用${变量名}就可以使用

我们首先给出一张用户参数设置图:

然后我们再给出一张使用图或者说我们的设置图:

数据文件

我们首先给出数据文件的相关定义:

  • CSV数据文件设置 —— 文件方式参数化

我们同样给出介绍:

# CSV文件?
# CSV文件是一种分行存储数据的文件

# CSV文件类型1(存在表行头)
username,password,isOP
user1,123456,True
user2,123321,False
user3,111111,True

# CSV文件类型2(无表头行)
user1,123456,True
user2,123321,False
user3,111111,True

# 如何定义?
# 我们可以在线程组下,创建配置元件的CSV 数据文件设置

# 具体作用?
# 针对一组参数,当每次使用都会使用不同数据信息

# 如何使用?
# 我们只需要在需要导入的地方采用${变量名}就可以使用

我们首先给出一张CSV文件导入Jmeter的展示图:

我们在使用时,同样采用$符进行数据导入,注意key值是我们在CSV数据文件设置里设置的变量名称:

函数参数

最后我们介绍一下函数参数:

  • 函数 —— 随机数据

我们同样给出基本介绍:

# 如何定义?
# 我们点击工具栏-选择函数助手对话框-弹出对话框-选择函数类型(这里我们仅介绍__counter计数器)

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

# 如何使用?
# 我们只需要在需要导入的地方采用${函数名}就可以使用

我们给出函数定义界面展示:

最后我们给出一个数据使用展示:

汇总展示

最后我们分别给出四种参数化处理的优缺点:

# 全局变量
# 作用:定义全局变量
# 局限性:每次取值(无论用户)都是固定值

# 用户参数
# 作用:保证不同用户针对同一参数,取到不同数据
# 局限性:用户在多次循环中会取到同一参数,导致数据重复

# 数据文件
# 作用:保证不同用户在不同循环中取到不同参数
# 局限性:需要手动设置数据,当用户循环过多,数据设置过多显得繁杂

# 函数参数
# 作用:自动生成不重复的数据,让每个用户每次循环都获取到不同的数据,且不需要提前定义
# 局限性:针对特定要求的场景,无法使用,泛用性较低(例如需要输入正确的账号密码进行登录时)

Jmeter断言介绍

下面我们来介绍Jmeter中的结果自动判断工具:

  • 我们的Jmeter本身有一个响应码自动判断,若结果并非200就会进行报错显示
  • 但是存在某些情况,即使响应码为200但也可能因为结果不对从而导致功能不符合需求
  • 所以我们需要学习断言,我们采用断言来完成字段的匹配,若字段不符合我们的需求则报错显示

响应断言

我们首先给出一张响应断言页的图片:

由于页面内容过多无法在图中展示所有字段含义,我们单独在下面介绍上述字段意义:

# 1.响应断言下方的名称和注释就是该响应断言的展示属性

# 2.apply to 这里我们选择默认 Main sample only 即可

# 3.测试字段主要是指我们是根据response的哪一部分来进行断言匹配
# 响应文本:来自服务器的响应文本,即主题
# 响应代码:响应状态码,例如200
# 响应信息:响应的信息,例如OK
# 响应头:响应头部
# 请求头:请求头部
# URL样本:请求URL路径
# 文本:响应的整个文本信息
# 请求数据:请求数据
# 忽略状态:请注意这里是复选框,因为我们的断言有响应码自动判断机制,如果我们需要判断响应码为非200状态,我们需要将其勾选防止报错

# 4.模式匹配规则
# 包括:文本包含指定的正则表达式
# 匹配:整个文本完全匹配指定的正则表达式
# 相等:整个返回结果文本完全匹配指定的字符串
# 字符串:返回结果文本包含指定的字符串
# 否:当存在多个测试模式时,默认为and(当全部满足才通过断言),如果勾选这里相当于!(全部不满足才通过断言)
# 或者:当存在多个测试模式时,默认为and(当全部满足才通过断言),如果勾选这里相当于or(存在一个满足就通过断言)
# 当然否和或者你也可以一起使用,相当于!or(存在一个不满足就通过断言)

# 5.测试模式
# 我们可以添加多个测试模式
# 测试模式其实就是断言的判断值,与response进行比较

# 其实整体如果采用pytest展示
# 结果值 比较方式 预期值 --> ${测试字段} ${模式匹配规则} ${测试模式}
# text == "百度一下,你就知道"

我们使用断言一般是放在请求的下层,当请求执行后就会采用请求返回的response来进行断言判断:

JSON断言

下面我们来介绍JSON断言,同样我们直接给出一张图片:

我们已经介绍过上述概念了,我们首先给出一个请求所获取的返回结果:

下面我们来获取上述JSON中的某个字段来进行匹配判断:

时间断言

除了上述我们对结果进行断言判断外,我们有时还需要进行性能测试,我们就需要判断在规定时间内是否满足条件:

  • ”断言持续时间”就是专门用来进行时间判断的断言

我们直接给出一张断言持续时间界面图:

我们同样给出一个简单的结果实例展示:

Jmeter关联介绍

我们在使用Jmeter时难免会遇到关联关系:

  • 当请求之间有依赖关系,就被称为关联
  • 例如一个请求的请求参数是另一个请求的请求响应结果

正则表达式提取器

我们首先来介绍正则表达式提取器:

# 正则表达式我这里给出简单定义,因为大部分人之前应该已经学习过这部分知识
# 就是一个公式,或者说一套规则,使用这套规则可以从任意字符串中提取出想要的数据内容

# 公式格式:左边界 + (匹配符号) + 右边界
# 我们可以通过该公式进行其部分数据内容的提取

# 我们常用的匹配符号主要包含以下三种:
# .:是通配符,可以代表任意字符(除换行回车)
# *: 代表前面的字符出现0次或者多次
# .*匹配规则:找到左边界值后,往右查找有边界,找到最后面的右边界,中间的所有数据都被记录下来
# ?: 代表非贪婪匹配,找到左边界后,往右查找匹配右边界,只要有匹配的右边界就停止继续查找;再次查找

# 1. 正常响应结果查找

# 公式格式:左边界(.*)右边界
# 这种就是获取结果的一种表达,但是该公式会导致如果存在多个标签符号,可能会出现跨越多个标签的结果
# 例如如果我们使用 <title>(.*)</title>
# 如果我们寻找的文本是"<title>百度一下,你就知道</title><title>百度一下,你就知道</title>"
# 上述情况我们就会提取到 "百度一下,你就知道</title><title>百度一下,你就知道"

# 公式格式:左边界(.*?)右边界
# 经过上述版本的优化非贪婪匹配,我们获取到第一个右边界就停止匹配
# 例如如果我们使用 <title>(.*?)</title>
# 如果我们寻找的文本是"<title>百度一下,你就知道</title><title>百度一下,你就知道</title>"
# 上述情况我们就会提取到 "百度一下,你就知道"

# 2. 文本数据结果查找

# 我们在使用过程中也可能出现以下格式:(分别表示 城市号、地区号、个人号码)
021-1234-1234
022-1234-1235
023-1234-1236
024-1234-1237
025-1234-1238
026-1234-1239
027-1234-1230

# 那么我们在匹配时就可以采用多个正则表达式进行匹配
# 我们可以使用:(.*?)-(.*?)-(.*?)\n 进行匹配,需要注意\n,因为我们的数据是存在换行的
# 最后我们还需要注意,我们这里由于是多行数据,所以最后我们的获取的数据其实也是多行的,我们后续是需要进行处理的

我们首先给出案例图来进行介绍:

我们首先给出正则表达式的正常使用示例图:

然后我们通过一张图来展示模板和匹配数字组的格式:

XPath提取器

下面我们来介绍XPath提取器,其实就是一个html提取器:

  • XPath提取器主要针对HTML格式的响应结果数据进行提取

我们在Selenium的介绍文章里已经介绍过XPath的具体匹配原则,这里我把介绍文本粘贴了一下方便大家查看:

# 首先我们还是给出XPath的使用格式
element = driver.find_element(By.XPATH,xpath)


# XPath一般分为四种定位方法,我们会在下面一一展示


# 1. 路径-定位
# 路径定位一般划分为绝对路径定位和相对路径定位

# 绝对路径定位:以 /html根节点 开始,使用/来分隔元素层级
# 例如/html/body/div/fieldset/p[1]/input,表示html层级下的body层级下的....的第一个p下的input元素
# 需要注意我们的html元素是以1开头,并不是以0开头,这里的1就是指一组p标签的第一个元素
driver.find_element(By.XPATH,"/html/body/form/div/fieldset/p[1]/input").send_keys("admin")

# 相对路径定位:以 //确定元素 开始,后续使用/来分隔元素层级
# 例如//p[@id='p1']/input,表示id为p1的p标签元素下的input元素
# 我们通常使用//来表示第一个可以确认的相对路径的元素,而这个元素通常采用标签名开头,我们可以使用[]来加上其对应的属性来确定元素
# 我们通常在[]里添加单个属性或多个属性来确定元素,我们通常使用@属性名=属性值的格式来表示,例如@id='p1'
driver.find_element(By.XPATH,"//p[@id='p1']/input").send_keys("123")


# 2. 利用元素属性-定位
# 一个元素通常会有多个属性,包括id,name以及自定义属性等
# 例如//input[@id='passwordA'],表示该id为passwordA的input元素
driver.find_element(By.XPATH,"//input[@id='passwordA']").send_keys("123")



# 3. 属性与逻辑结合-定位
# 如果我们出现元素内含有多个属性,且每个属性都有多个元素共享,我们就不能使用单个属性进行元素定位
# 所以我们需要使用逻辑方法来进行多属性判定,例如and,or等方法
driver.find_element(By.XPATH,"//input[@id='passwordA' and @placeholder='密码A']").send_keys("123")


# 4. 层级与属性结合-定位
# 如果通过元素自身的信息不方便直接定位到该元素,则可以先定位到其父级元素,然后再找到该元素
# 例如我们所需要定位的input上没有任何独立的属性,但是它的父类有独立属性,那么我们就可以根据父元素去定位子元素
driver.find_element(By.XPATH,"//*[@id='p1']/input").send_keys("123")


# 最后我们介绍几个XPATH的常用的延申内置属性方法
# 下面的*表示任意元素,这个是HTML中所定义的内容

# 文本内容是xxx的元素
driver.find_element(By.XPATH,"//*[text()="xxx"]")

# 属性中含有xxx的元素
driver.find_element(By.XPATH,"//*[contains(@attribute,'xxx')]")

# 属性以xxx开头的元素
driver.find_element(By.XPATH,"//*[starts-with(@attribute,'xxx')]")

那么我们首先还是给出XPath的展示图:

我们同样给出一张简单示例图:

JSON提取器

最后我们再来介绍一个JSON提取器,同样也是很简单的格式:

  • JSON提取器主要针对返回结果是JSON的响应结果数据进行提取

我们同样首先给出一张展示图并进行解释:

我们给出一张简单实例图解释:

Jmeter属性介绍

下面我们来介绍Jmeter的属性相关信息:

  • 我们前面使用的关联仅仅能在同一个线程组中进行使用,若我们想在不同线程组中使用就需要采用属性
  • 我们需要将我们所需要使用到的数据定义成Jmeter的全局变量,然后我们才能在不同线程组中使用该属性

Jmeter属性的设置同样需要函数来进行set和get操作:

  1. 首先我们需要有一个线程组1,然后线程组1里调用请求,我们采取JSON取样器获得请求中的city属性:

  1. 我们在获取数据之后,我们首先需要去创建函数,我们可以直接书写函数,也可以采用工具书写:

  1. 然后我们需要采用一个BeanShell取样器来进行函数执行:

  1. 如果我们希望调用我们定义的全局变量,我们同样需要使用函数,我们同样去获取函数:

  1. 最后我们只需要在另一个线程组里的请求里直接使用该函数即可,不需要额外操作:

Jmeter数据库连接

首先我们介绍一下Jmeter连接数据库的主要作用:

  • 用作请求参数化:例如登录界面所需账号密码,可以直接从数据库获取
  • 用作结果的断言:例如我们通过查询获取的数据,我们可以判断该数据是否真实存在,与数据库信息进行比较
  • 用作清除无用数据:当我们重复使用某功能时,可能存在某个字段不能重复使用,那么我们就需要在调用该功能之前删除该字段
  • 用作准备测试数据:当我们需要大量数据时,我们可以直接从数据库中获取大量数据进行调用

接下来我们就来讲解如何进行数据库连接:

  1. 首先我们需要对Jmeter添加对应的数据库jar包,下载后放在lib目录的ext目录下即可(下载方法在末尾):

  1. 然后我们在Jmeter里面配置JDBC Connection Configuration信息:

  1. 然后我们就可以通过JDBC请求来书写数据库代码来进行数据获取:

  1. 最后我们就可以采用这个JDBC Request去做一些断言之类的操作:

Jmeter逻辑控制器

我们在进行Jmeter操作的时候可能会进行过滤或者重复操作等,我们就会使用到逻辑控制器

If逻辑控制器

首先我们来介绍if逻辑控制器:

  • If逻辑控制器用来控制它下面的测试元素是否执行

然后我们给出一张if逻辑控制器的展示图进行参数介绍:

while逻辑控制器

下面我们来介绍while逻辑控制器:

  • 当我们需要某些特定语句去进行多次执行时,我们可以采用循环逻辑控制器
  • 如果我们该线程组下所有请求都在while逻辑控制器内,那么和线程组中控制循环次数的效果是一样的,这里就是为了单个请求做重复操作而设置的

我们直接给出逻辑控制器的展示图进行参数介绍:

Foreach逻辑控制器

最后我们介绍一个ForEach逻辑控制器,它是用于对组中元素均执行所创建的控制器:

  • 一般和用户自定义变量和正则表达式一同使用,用于使用该组中所有元素去执行请求

我们首先给出Foreach逻辑控制器的展示界面:

我们这里只介绍foreach如何与用户自定义变量来结合使用,其实原理都是相同的,针对组我们都可以采用foreach进行遍历操作:

  1. 定义用户自定义变量:

  1. 书写foreach控制器:

  1. 最后我们在HTTP请求中调用我们的kw即可,我们会在结果树中查看到三个结果:

Jmeter定时器介绍

最后我们来介绍Jmeter中最常用的三种定时器:

  • 定时器主要是方便我们通过控制dps和time来进行压力测试或性能测试等

同步定时器

我们首先来介绍同步定时器:

  • 阻塞线程,当在规定时间内达到一定线程数后,将这些线程一同释放,主要用于进行并发压力测试

我们直接介绍同步定时器的展示界面:

常数吞吐量定时器

下面我们来介绍常量吞吐量定时器:

  • 用于控制单个用户的dps查询速度,常用于进行稳定测试或长时间压力测试

我们直接给出常数吞吐量定时器的展示界面:

固定定时器

最后我们来介绍固定定时器:

  • 用于控制该请求在多久之后进行执行,用于验证一些时间关系

我们直接给出固定定时器的展示界面:

结束语

这篇文章中详细介绍了性能测试以及性能测试工具Jmeter的详情使用,希望能为你带来帮助

下面给出我学习和书写该篇文章的一些参考文章,大家也可以去查阅:

  1. 黑马课程:01.性能测试_阶段总体目标和课程安排_哔哩哔哩_bilibili
  2. CSDN下载攻略:mysql数据库链接驱动jar包的下载(Jmeter中使用为例)_mysql驱动jar包下载-CSDN博客