目录
-
- 1. JMeter环境安装
-
- 1.1 安装JDK
-
- JDK下载
- 安装JDK
- 配置环境变量
- 校验是否安装成功
- 1.2 安装JMeter
-
- 下载JMeter
- 安装JMeter
- 配置环境变量
- 启动验证
- 界面汉化
- 修改主题
- 响应结果出现乱码
- 2. JMeter目录结构
-
- 2.1 bin目录
- 2.2 docs目录
- 2.3 printable_docs
- 2.4 lib目录
- 3. JMeter元件和组件
-
- 3.1 元件
-
- 概述
- 取样器
- 逻辑控制器
- 前置处理器
- 后置处理器
- 断言
- 定时器
- 测试片段
- 配置元件
- 监听器
- 接口自动化脚本实现过程
-
- 配置元件
- 前置处理器
- 取样器
- 后置处理器
- 断言
- 监听器
- 元件作用域
-
- 作用域的原则
- 元件的执行顺序
- 案例
- 使用示例
-
- 需求
- 步骤
- 3.2 组件
-
- 概述
- 线程组
-
- 特点
- 分类
- 参数
- HTTP请求
-
- 作用
- URL属性
- 参数
- 案例
-
- get请求1
- get请求2
- post请求1
- post请求2
- 察看结果树
-
- 作用
- 组成
-
- 取样器结果
- 请求
- 响应数据
- 4. JMeter参数化
-
- 4.1 概述
-
- 参数化测试定义
- JMeter常见参数化的方式
- 本质
- 案例
-
- 要求
- 步骤
- 4.2 用户定义的变量
-
- 作用
- 局限性
- 位置
- 案例
-
- 要求
- 步骤
- 4.3 用户参数
-
- 概述
- 作用
- 局限性
- 位置
- 案例
-
- 要求
- 步骤
- 4.4 CSV数据文件设置
-
- 概述
- 作用
- 局限性
- 位置
- 案例
-
- 要求
- 步骤
- 4.5 函数(_counter)
-
- 概述
- 作用
- 局限性
- 位置
- 案例
-
- 要求
- 步骤
- 结果分析
- 5. JMeter断言
-
- 5.1 概述
-
- 含义
- 常用断言
- 5.2 响应断言
-
- 作用
- 位置
- 参数
-
- 测试字段
- 模式匹配规则
- 测试模式
- 案例
-
- 要求
- 步骤
- 5.3 JSON断言
-
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 5.4 断言持续时间
-
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 6. JMeter关联
-
- 6.1 概述
-
- 案例
- 关联
- 常用关联方法
-
- 同一线程组内
- 不同线程组内
- 6.2 正则表达式关联
-
- 正则表达式
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 调试器
- 进阶
- 6.3 xpath关联
-
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 6.4 json关联
-
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 6.5 跨线程组关联
-
- 概述
- JMeter属性
-
- 作用
- 配置函数
- 函数执行
- 案例
-
- 要求
- 步骤
- 7. JMeter录制脚本
-
- 7.1 概述
- 7.2 JMeter录制脚本
-
- 含义
- 原理
-
- 操作步骤
- 过滤设置
- 抓不到包原因分析
- 8. JMeter直连数据库
-
- 8.1 使用场景
-
- 用作请求的参数化
- 用作结果的断言
- 清理垃圾数据
- 准备测试数据
- 8.2 配置直连数据库
-
- JDBC连接配置
-
- 参数
- 添加JDBC请求
-
- 参数
- 9. JMeter逻辑控制器
-
- 9.1 概述
-
- 常见逻辑控制器
- 9.2 如果(If)控制器
-
- 作用
- 位置
- 参数
-
- JS语法格式
- 函数形式
- 案例
-
- 要求
- 步骤
- 9.3 循环控制器
-
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 和线程组循环次数的区别
- 9.4 ForEach控制器
-
- 作用
- 位置
- 参数
- 案例
-
- 要求
-
- 用户定义的变量
- 正则表达式
- 步骤
-
- 用户定义的变量
- 正则表达式
- 10. JMeter定时器
-
- 10.1 概述
- 10.2 同步定时器
-
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 10.3 常数吞吐量定时器
-
- 概述
- 作用
- 位置
- 参数
- 案例
-
- 要求
- 步骤
- 10.4 固定定时器
-
- 案例
-
- 要求
- 步骤
1. JMeter环境安装
1.1 安装JDK
JDK下载
官网下载地址
安装JDK
可以默认也可以修改安装路径(这一步和环境变量有关)
配置环境变量
环境变量-系统变量,修改2处(这一步和JDK安装的路径有关,我这里安装在了D盘)
# 新增系统变量JAVA_HOME(JDK的安装地址)
D:\Java\jdk-17.0.2# Path中新增环境变量(JDK的bin路径)
D:\Java\jdk-17.0.2\bin
D:\Java\jdk-17.0.2\jre\bin# 如果后面升级JDK,Path中的变量也需要修改,所以更好的写法是
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin
校验是否安装成功
1.2 安装JMeter
下载JMeter
下载地址
这里我选择的是apache-jmeter-5.4.3.zip,这里需要的是jdk 1.8+的版本(JMeter和JDK版本需要对应)
安装JMeter
把下载的安装包,解压到某一目录下(安装目录中不能有中文/空格)
配置环境变量
和JDK环境变量配置相似
环境变量-系统变量,修改2处(这一步和JMeter安装的路径有关,我这里安装在了D盘)
# 新增系统变量JMETER_HOME(JMeter的安装地址)
D:\apache-jmeter-5.4.3# Path中新增环境变量
%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar
%JMETER_HOME%\lib\jorphan.jar
启动验证
法1. 直接双击bin目录下的jmeter.bat
法2. java -jar ApacheJMeter.jar
任意一种方式能启动说明安装成功
界面汉化
修改配置文件:bin/jmeter.propertites,修改语言为language=zh_CN,重启JMeter
修改主题
选项-外观
响应结果出现乱码
乱码:中文无法正常显示
修改配置文件:bin/jmeter.propertites,修改配置为sampleresult.default.encoding=UTF-8(原来是ISO-XXX)
修改完配置文件后重启JMeter才能使修改的配置生效
2. JMeter目录结构
2.1 bin目录
存放可执行文件和配置文件
2.2 docs目录
JMeter的api文档,用于开发扩展组件
2.3 printable_docs
用户帮助手册
2.4 lib目录
存放JMeter依赖的jar包和用户扩展所依赖的jar包
3. JMeter元件和组件
3.1 元件
概述
多个类似功能组件的容器(类似于类)
取样器
发送请求
逻辑控制器
控制语句的执行顺序
前置处理器
对请求参数进行预处理
后置处理器
对响应结果进行提取
断言
检查接口的返回结果是否和预期结果一致
定时器
设置等待
测试片段
封装一段代码,供其他脚本调用
配置元件
测试数据的初始化配置
监听器
查看JMeter脚本的运行结果
接口自动化脚本实现过程
配置元件
初始化测试数据
前置处理器
对请求参数进行赋值
取样器
调用GET/POST方法发送请求
后置处理器
提取响应中特定字段的值
断言
对提取出来的值与预期结果进行对比
监听器
控制台查看脚本运行结果
元件作用域
元件作用域是靠测试计划的树形结构中元件的父子关系来确定的
所有的组件都是以取样器为核心来运行的(如果在一个脚本里没有取样器,那么这个脚本就不会执行)
组件添加的位置不同,生效的取样器也不同
作用域的原则
- 取样器:核心,不和其他元件相互作用,没有作用域
- 逻辑控制器:只对其子节点的取样器和逻辑控制器起作用
- 其他元件:如果是某个取样器的子节点,则该元件只对其父节点起作用;如果父节点不是取样器,则其作用域是该元件父节点下的其他所有后代节点(包括子节点,子节点的子节点等)
元件的执行顺序
同一作用域下的不同类型元件:配置元件-前置处理器-定时器-取样器-后置处理器-断言-监听器
同一作用域下的多个相同类型元件:按照测试计划从上到下的顺序依次执行
案例
定时器1-请求1-定时器1-定时器2-请求2-定时器1-定时器3-请求3
使用示例
需求
使用JMeter访问百度首页接口,并查看请求和响应信息
步骤
- 测试计划里添加线程组-线程组
- 线程组-添加-取样器-HTTP请求
- 填写HTTP请求的相关请求数据
- 线程组-添加-监听器-察看结果树
- 点击启动按钮运行,并查看结果
3.2 组件
概述
实现独立的某个功能(类似于方法)
以取样器的组件为例,以下介绍3种重要的基本组件(JMeter基本组成部分)
线程组
线程组就是控制JMeter用于执行测试的一组用户
特点
- 可以模拟多人操作(修改线程数)
- 线程组可以添加多个,多个线程组可以并行或串行(勾选"独立运行每个线程组"可以实现串行)
- 取样器(请求)和逻辑控制器必须依赖线程组才能使用
- 线程组下可以添加其他元件下组件
分类
- 线程组:普通常用的线程组,可以看作一个虚拟用户组,线程组中每个线程都可以理解为一个虚拟用户;执行测试用例,可以有1个或多个(并行/串行)
- setup线程组:预测试操作,所有脚本之前执行
- teardown线程组:测试后操作,所有脚本之后执行
参数
- 线程数代表虚拟用户数,用户数越多,负载越大
- 循环次数代表运行时间,次数越多,运行时间越长
HTTP请求
作用
向服务器发送http和https请求(取样器)
如果协议部分不填,JMeter默认是http协议,端口默认是80
URL属性
协议、域名、端口、路径、请求方法、编码格式
参数
- 发送get请求:路径里填写参数(?键名=键值&键名=键值);参数列表中添加参数(名称、值)
- 发送post请求:参数列表中添加参数(和get的第二种方法相同,区别在于请求方法需要修改为post,form);消息体数据中添加请求体(form/json)
案例
get请求1
使用HTTP请求-路径来传递get请求参数
get请求2
使用HTTP请求-参数列表来传递get请求参数(需要注意这里协议是https而不是http)
post请求1
使用HTTP请求-参数列表来传递POST请求的form格式参数
post请求2
使用HTTP请求-消息体数据来传递POST请求的form格式参数
察看结果树
作用
查看HTTP请求的请求和响应结果
组成
取样器结果
查看响应头信息、响应状态码
请求
查看请求相关信息(URL,方法,参数)
响应数据
查看响应信息(状态码,响应体)
4. JMeter参数化
4.1 概述
如果要发送请求10次,每次请求发送不同的参数值,应该怎么做?引入参数化
参数化测试定义
用不同的测试数据调用相同的测试方法进行测试(用参数来替代固定的测试数据,参数是1个还是多个由自己来定义)
JMeter常见参数化的方式
-
用户定义的变量–全局变量
-
用户参数–为每个用户分配不同的参数值
-
CSV Data Set Config–文件方式参数化
-
函数–随机数据
-
(数据库/数据文件)
本质
实现测试数据和测试方法的分离
案例
要求
某支付系统,需要用1000个不同的用户登录,并使用添加不同的测试金额数据访问支付接口
步骤
- 准备csv数据文件,1000个登录的用户名密码
- 添加线程组
- 添加csv数据文件设置
- 添加HTTP请求–登录,使用读取的用户名密码
- 添加HTTP请求–支付,使用counter函数添加不同的测试金额
- 察看结果树
4.2 用户定义的变量
作用
定义全局变量
局限性
每次取值(无论是否相同用户)都是固定值
位置
线程组–添加–配置元件–用户定义的变量
案例
要求
使用用户定义的变量配置被测系统的协议、域名和端口(https://www.baidu.com:443)
步骤
- 添加3个变量(变量名、变量值)
- 添加HTTP请求,引用自定义的变量名(格式:${变量名})
- 运行,查看结果树
4.3 用户参数
概述
性能测试的时候有多个用户同时请求,每个用户在登录请求时需要使用不同的用户名密码进行登录,应该怎么做
作用
针对同一组参数,当不同的用户来访问时,可以获取到不同的值
局限性
同一个用户在多次循环时,取到相同的值
位置
线程组–添加–前置处理器–用户参数
案例
要求
第一个用户请求附带参数:name=“张三”&age=28;第二个用户请求附带参数name=“李四”&age=30(https://www.baidu.com)
步骤
- 添加线程组,线程数设置为2(表示模拟的用户数)
- 添加用户参数(第一列添加多个变量名,后续每一列为一组用户数据)
- 添加HTTP请求,引用自定义的变量名(格式:${变量名})(和用户定义的变量类似)
- 添加查看结果树
4.4 CSV数据文件设置
概述
性能测试时有多个用户登录,登录后循环添加商品,每次添加时商品的参数不同,应该怎么做
作用
让不同的用户或者同一用户在多次循环时,可以取到不同的值
局限性
需要手动进行测试数据的设置
位置
线程组–添加–配置元件–CSV数据文件设置
案例
要求
循环请求3次,每次请求时附带参数username,password,code的值不相同(https://www.baidu.com)
步骤
- 定义CSV数据文件
- 添加线程组,设置循环次数为3次
- 添加CSV数据文件设置
- 添加HTTP请求,引用自定义的变量名(格式:${变量名})(和用户定义的变量类似)
- 添加察看结果树
在vscode里编辑数据,最后修改文件后缀名为.csv
如果修改线程数为2,循环次数依旧为3,则会读取CSV文件中的所有6条数据
4.5 函数(_counter)
概述
性能测试时,如果模拟1000个用户,每个用户循环执行10万次添加商品操作,请求参数要求不同,应该怎么做
需要自动生成不重复的数据时,让每个用户每次循环都能取到不同的数据,且不需要提前定义
作用
计数函数,一般做执行次数统计使用
局限性
输入数据有特定业务要求时无法使用(如登录时的用户名,密码)
位置
菜单栏–函数助手对话框(倒数第2个菜单);快捷键ctrl+shift+F1
True:每个用户有自己的计数器
False:所有用户使用全局计数器
填写True/False后,点击生成,将生成的字符串复制粘贴到请求的取样器里即可
案例
要求
每个用户每次循环执行该脚本都可以使用不同的值(访问百度首页http://www.baidu.com/S?num=1)
步骤
- 添加线程组,设置虚拟用户数和循环次数
- 生成counter函数
- 添加HTTP请求,使用counter函数,格式${__counter(FALSE,)}
- 察看结果树
结果分析
查看结果树中看到的发送消息和HTTP取样器中配置的不一致?
- 察看结果树中最外层HTTP请求的请求信息和响应信息,应该与子结点中最后一个HTTP请求的请求消息和响应消息一致
- 配置的HTTP请求,应该与子结点中第一个HTTP请求的请求信息一致
- JMeter可以自动判断/处理响应状态码
5. JMeter断言
5.1 概述
手工执行用例时,可以用肉眼观察结果,使用工具代替手工执行用例时,如何判断用例是否通过?
含义
让程序自动判断预期结果是否和实际结果一致
JMeter在请求的返回层面,有个自动判断机制(响应状态码,如果状态码为4XX/5XX,判定为失败),但是请求成功了,并不代表结果一定正确,因此需要检测机制提高测试准确性
常用断言
- 响应断言
- JSON断言
- 持续时间断言
5.2 响应断言
作用
对HTTP请求的任意格式的响应结果进行断言
位置
线程组–HTTP请求–添加–断言–响应断言
参数
测试字段
实际结果
- 响应文本:来自服务器的响应文本,即主体
- 响应代码:响应的状态码,例如200
- 响应信息:响应的状态,例如OK
- 响应头
- 请求头
- URL样本:请求URL
- Document(text):响应的整个文档
- 忽略状态:忽略返回的响应状态码
模式匹配规则
比较方式
- 包括:文本包含指定的正则表达式
- 匹配:整个文本匹配指定的正则表达式
- 相等:整个返回结果的文本等于指定的字符串(区分大小写)
- 字符串:返回结果的文本包含指定字符串(区分大小写)
- 否:取反
- 或者:如果存在多个测试模式,勾选代表逻辑或(只要有一个模式匹配,则断言就是OK),不勾选代表逻辑与(所有都必须匹配,断言才是OK)
- 注意:相等和字符串模式都是普通字符串,而包括和匹配模式则是正则表达式
测试模式
预期结果,即填写指定的结果(可填写多个),添加和删除是进行指定内容的管理
案例
要求
- 让程序检查响应数据中是否包含"百度一下,你就知道"(请求https://www.baidu.com)
具体是否包含"百度一下,你就知道",可以先不配置响应断言,直接查看HTTP请求的响应数据,查找是否存在这样的内容
- 对一个HTTP请求添加多种响应断言(状态码),只有当响应断言为false时,才会报错
步骤
- 添加线程组
- 添加HTTP请求
- 添加响应断言
- 测试字段
- 匹配规则
- 测试模式
- 添加察看结果树
5.3 JSON断言
作用
对HTTP请求的JSON格式的响应结果进行断言
位置
线程组–HTTP请求–添加–断言–JSON断言
参数
- Assert JSON Path esists:用于断言的JSON元素的路径(实际结果)
- Additionally assert value:如果想要用某个值生成断言,则选择复选框
- Match as regular expression:使用正则表达式断言
- Expected Value:期望结果
- Expect null:如果希望为空,则选择复选框
- Invert assertion:反转断言,如果满足以上条件,则失败
案例
要求
让程序检查响应的JSON数据中,city对应的内容是否为北京(http://www.weather.com.cn/data/sk/101010100.html)
步骤
- 添加线程组
- 添加HTTP请求
- 添加JSON断言
- Assert JSON Path esists(实际结果),注意格式是$.字段.下一个字段
- 勾选Additionally assert value
- Expected Value(期望结果)
- 添加察看结果树
5.4 断言持续时间
作用
检查HTTP请求的响应时间是否超出要求范围
位置
线程组–HTTP请求–添加–断言–断言持续时间
参数
持续时间(毫秒):HTTP请求允许的最大响应时间,超过则认为失败
案例
要求
让程序检查响应时间是否大于100毫秒(访问https://www.jd.com)
步骤
- 添加线程组
- 添加HTTP请求
- 添加断言持续时间
- 添加察看结果树
6. JMeter关联
6.1 概述
案例
选择商品加入购物车
- 登录HTTP请求
- 登录HTTP响应(返回token信息)
- 加入购物车HTTP请求(带token信息)
- 加入购物车HTTP响应
关联
当请求之间有依赖关系,比如一个请求的入参是另一个请求返回的数据,此时就需要用到关联处理
常用关联方法
同一线程组内
-
正则表达式提取器:如果JSON提取器和XPath提取器都无法实现关联,使用正则表达式提取器进行补充–针对任意格式的响应数据(相对其他两种提取器,效率低)
-
XPath提取器:如果响应格式是HTML格式,优先使用XPath提取器进行关联
-
JSON提取器:如果响应格式是JSON格式,优先使用JSON提取器进行关联
不同线程组内
- JSON提取器+JMeter属性
- XPath提取器+JMeter属性
- 正则表达式提取器+JMeter属性
6.2 正则表达式关联
正则表达式
一个公式/一套规则,使用这套规则可以从任意字符串中提取出想要的数据内容
公式格式:左边界(匹配符号)右边界:可以提取出想要获取的数据内容.:是通配符,可以代表任意字符(除换行回车)
*: 代表前面的字符出现0次或者多次.*匹配规则:找到左边界值后,往右查找有边界,找到最后面的右边界,中间的所有数据都被记录下来
?: 代表非贪婪匹配,找到左边界后,往右查找匹配右边界,只要有匹配的右边界就停止继续查找;再次查找
左边界和右边界公式格式:左边界(.*?)右边界
<title>百度一下,你就知道</title><title>百度一下,你就知道</title>
<title>(.*?)</title>
原始文本:
021-1234-1234
022-1234-1235
023-1234-1236
024-1234-1237
025-1234-1238
026-1234-1239
027-1234-1230
要求:匹配出 城市号、地区号、个人号码三组(.*?)-(.*?)-(.*?)\n
- 通过一个正则表达式可以提取出多组数据,每组数据设置对应的左边界和右边界即可
- 每一组数据都可以有一个或者多个值
作用
针对任意格式的响应数据进行提取
位置
线程组–HTTP请求–后置处理器–正则表达式提取器
参数
- 引用名称:存放提取出的值的参数名称,供下一个请求引用,比如title,则用${title}引用它
- 正则表达式
符号 | 含义 |
---|---|
() | 括起来的部分就是要提取的 |
. | 匹配任何字符串 |
+ | 一次或多次 |
? | 非贪婪匹配,在找到第一个匹配项后停止 |
- 模板:用$$引用起来,如果在正则表达式中有多个提取值,则可以是$2$$3$,表示解析到的第几个值给title
- 匹配数字:0代表随机取值,-1代表全部取值,1代表取第1个值(表示正则表达式匹配到了多处字符串)
- 缺省值:如果参数没有取到值,则默认给一个值让它取
案例
要求
- 请求http://www.itcast.cn/,获取网页的title值/把第5个校区地址作为参数传递(方法1. 直接提取第5个参数保存到area中,http请求时直接调用引用名称;方法2. 获取全部地址信息(匹配数字修改为-1),然后在http请求百度的时候筛选出第5个)
- 请求https://www.baidu.com/,把获取到的title作为请求参数
步骤
调试器
可以方便查看正则表达式提取到的内容
位置:线程组–添加–取样器–调试取样器(设置匹配数字为-1)
运行以后,察看结果树–调试取样器–响应结果里会有所有获取到的area值(格式是area_1, area_2, …,据此修改HTTP请求百度中的请求路径为wd=${area_5})
方法2是以列表索引的方式来引用,格式:${变量名_索引},索引从1开始
进阶
获取传智播客的首页地址,把第5个校区地址作为参数传递(span为地址/后面带一、二、三)
地址格式1:<p><span>地址一</span>昌平区建材城西路金燕龙办公楼一层</p>
地址格式2:<p><span>地址</span>上海市浦东新区航头镇航都路18号万香创新港</p>
6.3 xpath关联
作用
针对HTML格式的响应结果数据进行提取
//标签名
位置
线程组–HTTP请求–添加–后置处理器–XPath提取器
参数
- use Tidy(tolerant parser):当需要处理的页面是HTML格式时,必须选中该选项;当需要处理的页面是XML或者XHTML格式时,取消选中该选项
- 引用名称:存放提取出的值的参数名称
- XPath Query:用于提取值的XPath表达式
- 匹配数字:如果查询出许多结果,可以选择提取哪个。0随机、-1提取所有结果、1第一个值
- 缺省值:参数的默认值
案例
要求
获取传智播客首页的title,并作为参数传递
步骤
- 添加线程组
- 添加HTTP请求-传智播客
- 添加XPath提取器
- 添加HTTP请求-百度
6.4 json关联
作用
针对JSON格式的响应结果数据进行提取
位置
线程组–HTTP请求–添加–后置处理器–JSON提取器
参数
Names of created variables:存放提取出的值的参数名称
JSON Path Expressions:JSON路径表达式
Match No:如果JSON路径匹配出许多结果,则可以选择提取哪个。0随机、-1提取所有结果、1第一个
Default Values:参数的默认值
案例
要求
请求获取天气的接口(http://www.weather.com.cn/data/sk/101010100.html)获取返回结果中的城市名称"北京"
把获取到的城市名称作为参数访问百度
步骤
- 添加线程组
- 添加HTTP请求-天气
- 添加JSON提取器
- 添加HTTP请求-百度
- 察看结果树
6.5 跨线程组关联
概述
当有关联关系的两个请求在同一个线程组中时,可以使用三种提取器的变量来实现数据传递
当有关联关系的两个请求在不同线程组中时,如何进行数据传递(变量不可以跨线程组传递,所以需要设置全局变量)
JMeter属性
作用
实现跨线程组的数据传递时,需要使用JMeter属性
配置函数
setProperty函数:将值保存为JMeter属性
property函数:在其他线程组中使用property函数读取属性
函数执行
setProperty函数执行时(保存JMeter属性),需要通过BeanShell取样器来执行
property函数(读取属性),在其他线程组中使用property函数
案例
要求
线程组1:请求获取天气的接口(http://www.weather.com.cn/data/sk/101010100.html)获取返回结果中的城市名称"北京"
线程组2:把获取到的城市名称作为参数访问百度
步骤
- 添加线程组1
- 添加HTTP请求-天气
- 添加JSON提取器
- 添加BeanShell提取器(将JSON提取器提取的值保存为JMeter属性)
- 添加线程组2
- 添加HTTP请求2-百度(读取JMeter属性)
- 添加察看结果树
- 防止2个线程组并行执行,需要在测试计划中设置独立运行每个线程组
7. JMeter录制脚本
7.1 概述
有API文档时,可以根据API文档的定义来编写HTTP接口测试脚本
没有API文档时,应该如何编写HTTP接口测试脚本
7.2 JMeter录制脚本
含义
在没有接口文档的旧项目中,快速录制web页面产生的http接口请求,帮助编写接口测试脚本
原理
JMeter作为代理服务器来拦截和转发请求与响应数据
操作步骤
- 添加HTTP代理服务器并进行配置:测试计划–添加–非测试元件–HTTP代理服务器–配置服务器的代理参数
- 开启windows系统的代理服务器设置
- 启动HTTP代理服务器,开始录制
- 在浏览器中进行操作(访问网页,发送请求),成功以后就可以在线程组里看到抓取到的接口请求了
过滤设置
分为包含模式(匹配则抓取)和排除模式(匹配则丢弃)
.*.jpg
.*.jpeg
抓不到包原因分析
- 过滤规则设置有问题
- 重启JMeter代理服务器或者重启JMeter
- 换浏览器(Chrome,IE)
- 检查PC机中的代理设置是否处于可用状态
- 拔掉网线,抓包
8. JMeter直连数据库
8.1 使用场景
用作请求的参数化
登录时需要的用户,可以从数据库中查询获取
用作结果的断言
添加到购物车,下订单,检查接口返回的订单号,是否和数据库中生成的订单号一致
清理垃圾数据
添加商品(商品名/编号等不能重复),再执行该脚本不能成功,需要在下次执行之前删除该商品数据
准备测试数据
通过数据库来准备大量(几十万条)的性能测试数据
8.2 配置直连数据库
-
添加MySQL驱动jar包
将MySQL驱动jar包放入到lib/ext目录下,重启JMeter
-
配置数据库连接信息
线程组–添加–配置元件–JDBC Connection Configuration
JDBC连接配置
参数
- Variable Name:mysql数据库连接池的名称(JDBC请求时要引用)
- Database URL:jdbc:mysql://localhost:3306/tsshop2.0
- 组成:协议+数据库IP+数据库端口+连接的数据库名称
- JDBC DRIVER class:com.mysql.jdbc.Driver(MySQL驱动包位置固定格式–下拉框选择)
- Username:root(连接数据库的用户名)
- Passward:数据库密码
添加JDBC请求
线程组–取样器–JDBC Request
参数
- Varibale Name:数据库连接池的名字,需要与JDBC Connection Configuration的Variable Name Bound Pool名字保持一致
- Query Type:查询操作选择"Select Statement";增加、删除、修改操作选择"Update Statement"
- Query:填写SQL语句,末尾不要加";"
- Variable Name:保存SQL语句返回结果的变量名
9. JMeter逻辑控制器
9.1 概述
可以按照设定的逻辑控制取样器的执行顺序
常见逻辑控制器
- 如果(If)控制器
- 循环控制器
- ForEach控制器
9.2 如果(If)控制器
作用
If控制器用来控制它下面的测试元素是否运行
位置
线程组–添加–逻辑控制器–如果(If)控制器
参数
JS语法格式
“${name}”==“baidu”
不勾选Interpret Conditions as Variable Expression
函数形式
jexl3函数,勾选Interpret Conditions as Variable Expression
函数的方式访问速度更快点
案例
要求
使用用户定义的变量,定义一个变量name,name的值可以是baidu或itcast
根据name的变量值实现对应网站的访问
步骤
- 添加线程组
- 添加用户定义的变量
- 添加If控制器,判断name是否等于baidu
- 添加HTTP请求,访问百度
- 添加If控制器,判断name是否等于itcast
- 添加HTTP请求,访问itcast
- 添加察看结果树
9.3 循环控制器
作用
设置循环次数,来实现循环发送请求
位置
线程组–添加–逻辑控制器–循环控制器
参数
循环次数
案例
要求
循环访问百度10次
步骤
- 添加线程组
- 添加循环控制器,设置循环次数10
- 添加HTTP请求
- 添加察看结果树
和线程组循环次数的区别
线程组循环次数对线程组下所有HTTP请求有效,循环控制器循环次数对子节点下HTTP请求有效
关联:
循环控制器次数为M,线程组循环次数为N
循环控制器下的请求运行M*N次
线程组下非循环控制器的请求运行N次
9.4 ForEach控制器
作用
一般和用户定义的变量或者正则表达式提取器一起使用,读取返回结果中一系列相关的变量
位置
线程组–添加–逻辑控制器–ForEach控制器
参数
- 输入变量前缀:要读取的输入变量的前缀
- 开始循环字段:要读取的输入变量后缀数字最小值-1
- 结束循环字段:要读取的输入变量后缀数字最大值
- 输出变量名称:读取输入变量的值后保存的新变量名,用于后续HTTP请求来引用
案例
要求
用户定义的变量
有一组关键字[hello, python, 测试],使用用户定义的变量存储
依次取出关键字,并在百度搜索,例如https://www.baidu.com/S?wd=hello
正则表达式
访问itcast首页,获取首页中地址信息,全部保存下来
依次取出地址关键字,并在百度搜索,例如https://www.baidu.com/S?wd=地址
步骤
用户定义的变量
- 添加线程组
- 添加用户定义的变量/正则表达式(返回一组变量,特点是相同的变量名+连续的数字后缀)
- 添加ForEach控制器
- 添加HTTP请求-百度(引用foreach控制器中保存的新变量名,比如${kw})
- 添加察看结果树
正则表达式
- 添加线程组
- 添加HTTP请求1-itcast
- 正则表达式提取器,提取出所有地址信息
- 添加foreach控制器,读取提取出的地址信息
- 添加HTTP请求2-百度
- 添加察看结果树
10. JMeter定时器
10.1 概述
如何模拟1w人同时使用电商网站?(线程组中设置线程数,相对并发)
如何模拟1w人同时进行电商网站中的抢购活动/秒杀活动?(同步定时器,绝对并发)
10.2 同步定时器
作用
阻塞线程(累积一定请求),当在规定时间内达到一定线程数量,这些线程会在同一个时间点一起释放,瞬间产生很大压力
JMeter中叫同步定时器,Loadrunner中叫集合点
测试抢购、秒杀或者抢红包等高并发场景时使用
位置
线程组–HTTP请求–添加–定时器–Synchronizing Timer
参数
- Number f Simulated Users to Group by:模拟用户数量,即指定同时释放的线程数数量(0表示设置为线程组中线程数量)
- Timeout in milliseconds:超时时间,超时多少毫秒后,同时释放指定的线程数
- 设置为0,该定时器会等待线程数达到了设置的线程数才会释放,没有达到设置的线程数会一直死等
- 大于0,如果超过Timeout in milliseconds设置的最大等待时间后还没达到设置的线程数,将不会再等待,释放已到达的线程,默认为0
案例
要求
模拟100个用户同时访问百度首页,统计各种高并发情况下运行情况
步骤
- 添加线程组,设置线程数100
- 添加HTTP请求
- 添加同步定时器
- 设置并发线程数:同时发送请求的虚拟用户数
- 设置超时时间:
- 不设置的话,如果没有达到设置的线程数会一致死等
- 不能设置太小:等待时间后还没达到设置的线程数,会释放已到达的线程(达不到并发的效果)
- 添加察看结果树
- 添加监听器–聚合报告
10.3 常数吞吐量定时器
概述
稳定性测试时,要求模拟用户真实的业务场景
如果真实的业务场景QPS为20,如何精确模拟
需要按照指定的吞吐量发送请求时,可以使用常数吞吐量定时器
作用
让JMeter按照指定的吞吐量执行,以每分钟为单位
位置
线程组–HTTP请求–添加–定时器–Constant Throughput Timer
参数
Target Throughput:目标吞吐量的设置(每个用户每分钟发送的请求数)
计算方法:QPS*60/线程数
案例
要求
模拟用户真实业务场景的需求:20QPS
如果线程数设置为1,则目标吞吐量设置为20*60=1200
如果线程数设置为2,则目标吞吐量设置为1200/2 = 600
步骤
- 添加线程组,循环次数设置为永远
- 添加HTTP请求
- 添加常数吞吐量定时器
- 添加察看结果树
- 添加监听器-聚合报告
10.4 固定定时器
案例
要求
IHRM系统登录错误3次后,锁定1分钟,1分钟后重新输入正确的用户名密码登陆成功
步骤
- 添加线程组
- 添加HTTP请求1-错误1次
- 添加HTTP请求2 – 错误2次
- 添加HTTP请求3 – 错误3次
- 添加HTTP请求4 – 正确用户名密码
- 在HTTP请求4下,添加固定定时器
- 添加查看结果树