一,安装
1,下载
2,安装
jmeter解压即用,以windows为例,进入其/bin目录下,双击jmeter.bat即可启动
二,TCP接口压测案例
1,选择语言(中文)
步骤:1.Options → 2.Choose Language → Chinese (Simplified)
2,测试计划
1)测试计划名称:可以为本次压测定义测试计划名称
2)用户自定义全局变量:可以在此处定义全局变量,如IP、端口等,可以在需要处使用${名称}
的方式引用
3)保存:定义完测试计划的基本信息后,可以Ctrl + S 将测试计划脚本保存到本地,防止丢失
3,线程组
1)作用:线程组定义的是请求测试计划中接口的并发用户数及其行为
2)添加线程组:在测试计划右键 → 添加 → 线程(用户) → 线程组
3)核心属性:
①线程数:并发用户数
②Ramp-Up时间(秒):多少秒启动定义好的线程数,如线程数定义为60,Ramp-Up时间定义为60,则1秒启动一个线程,60秒后60个线程并发
③循环次数:每个线程请求多少次,如定义为1,线程数定义为60,则请求60次,如定义为永远,可以和调度器同时使用,测试指定时间内的并发
④调度器-持续时间(秒):请求的时间
4)在编写脚本阶段,可以使用默认值,每个接口请求1次,做脚本的测试工作
4,TCP取样器配置
1)作用:TCP取样器配置可以对要配置的TCP取样器做一个默认配置,如IP、端口、超时时间等,当一个线程组下配置了多个TCP取样器(接口)时,如取样器不配置信息,则取TCP取样器配置中的默认值,如有自定义配置,则取自定义配置
2)添加TCP取样器配置:在线程组右键 → 添加 → 配置元件 → TCP取样器配置
涵义:取样器即用于模拟不同类型请求的组件,常用的有TCP取样器、Http取样器,可以理解为请求指定接口的客户端
3)核心属性:
①TCPClient classname:TCP客户端类名(一般默认即可),该参数一般有三个值:
-
org.apache.jmeter.protocol.tcp.sampler.TCPClientImpl(以文本编辑器中的纯文本作为内容发送)
-
org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl(以文本编辑器中所编辑的16进制字符(hex)内容为基础转换为二进制的字节内容进行发送)
-
org.apache.jmeter.protocol.tcp.sampler.LengthPrefixedBinaryTCPClientImpl(在BinaryTCPClientImpl基础上默认以发送内容的长度以字节前缀进行填充)
②服务器名称或IP:自定义即可,可以使用${}方式引用测试计划中定义的自定义变量
③端口号:自定义即可,可以使用${}方式引用测试计划中定义的自定义变量
④超时(毫秒)-连接/响应:连接端口和接收响应的超时是时间,按照实际情况填写即可
⑤关闭连接:请求完成之后关闭TCP连接
⑥要发送的文本:请求报文内容,最好每个取样器中分开配置
4)配置案例:
5,TCP取样器
1)作用:TCP取样器在压测时,作为对应后端具体某一只TCP接口的客户端
2)添加TCP取样器:在线程组右键 → 添加 → 取样器 → TCP取样器
3)核心属性:
①名称:TCP取样器名称
②要发送的文本:请求报文内容,可以通过计数器
、jmeter内置函数
、CSV数据文件
、用户自定义变量
等配置动态报文
4)配置案例:
6,计数器
1)作用:类似序列号,主要可用于生成流水号
2)添加计数器:在线程组右键 → 添加 → 配置元件 → 计数器
3)核心属性:
①名称:计数器名称
②Starting value:起始值
③递增:每次增加的值
④Maximun value:最大值
⑤数字格式:定义最终输出的数据格式,如5位序列号,不足左补0,则定义为00000
即可
⑥引用名称:即在测试流程中引用的key,如定义为seq
,则在报文中使用 ${seq}
即可引用到此计数器
⑦与每用户独立的跟踪计数器:是否线程隔离,每个线程(用户)自己独立的计数器,全局计数器不选即可
4)配置案例:
引用:
7,CSV 数据文件设置
1)作用:可以将一些Jmeter内置方式无法正确生成的动态业务数据,使用CSV文件编写,如能通过校验的客户号、账号等
2)添加CSV 数据文件设置:在TCP取样器右键 → 添加 → 配置元件 → CSV Data Set Config
3)核心属性:
①名称:CSV数据文件设置名称,任意
②文件名:CSV文件绝对路径
③文件编码:CSV文件编码,一般使用UTF-8
④变量名称(西文逗号间隔):定义从CSV文件中读取的变量名,使用英文命名,多个变量用逗号分隔,与CSV文件每一列数据的顺序保持一致,接口报文中可以使用${变量名称}
方式引用数据
⑤忽略首行(只在设置了变量名称后才生效):忽略第一行数据,如果CSV文件中第一行不是数据行而是数据的定义名称,设置为True,否则设置为False
⑥分隔符(使用‘\t’代表制表符):数据分隔符,一般CSV文件使用英文逗号分隔
⑦是否允许带引号?:数据是否存在引号(当单元格中存在特殊字符时,CSV会使用双引号包裹此单元格的数据)
⑧遇到文件结束符再次循环?:设置为True即可
⑨遇到文件结束符停止线程?:设置为False即可
⑩线程共享模式:设置为所有线程或当前线程组
4)配置案例:
步骤一:编写CSV文件,如:
步骤二:配置CSV数据文件设置
步骤三:在接口报文中引用对应的数据变量
8,断言
作用:用来判断取样器获得的响应结果是否符合预期,常用的断言类型有:
-
响应断言:可以判断响应码、响应头、响应体、请求头、请求体等数据中是否包含、完全匹配、字符串包含符合预期的数据
-
JSON断言:可以使用JsonPath语法获取JSON响应体中具体的值,判断其是否符合预期
8.1,响应断言
1)添加响应断言:在TCP取样器右键 → 添加 → 断言 → 响应断言
2)核心属性:
①名称:响应断言名称,任意
②Apply to:断言应用于何处,一般使用默认即可
③测试字段:需要断言的主体,一般有响应文本(响应体)、响应代码、响应信息几个常用值,通常使用响应文本即可
④模式匹配规则:
-
包括:确保响应中包含指定的文本
-
匹配:使用正则表达式检查响应内容是否符合预期模式
-
相等:完全匹配响应内容与预期的值
-
字符串:检查响应是否包含指定的子字符串
-
否:选中则取反
-
或者:存在多个成立条件时,其之间的关系运算方式,选中则是or运算符,不选则是and运算符
⑤测试模式:预期要检查的内容,可以是字符串、正则表达式等
3)配置案例:
涵义:在主取样器中,判断响应体是否包含字符串"RetCd":"AAAAAAA"
,如果包含则成功,否则失败
8.2,JSON断言
1)添加JSON断言:在TCP取样器右键 → 添加 → 断言 → JSON断言
2)核心属性:
①名称:JSON断言名称,任意
②Assert JSON Path exists:JsonPath表达式
③Additionally assert value:勾选后,才可以可以添加期望值输入框中输入内容
④Match as regular expression:勾选后支持正则表达式匹配
⑤Expected value:期望值
⑥Expect null:勾选后,期望值为null
⑦Invert assertion (will fail if above conditions met):反转断言(如果满足上述条件,则将失败)
3)配置案例:
涵义:在响应体中获取JSON报文,转为JSON对象,获取其下一级key为SysHead的JSON对象,在获取其key为RetCd的值,期望值时AAAAAAA,如果不是则失败,是则成功
注意:适用于响应报文为完整的JSON对象或JSON数组格式的接口,如果不是JSON格式会产生报错,常见于TCP请求中,响应报文会拼接上报文长度
9,提取器
作用:用来提取响应信息中的数据,存入上下文,常用于从一个请求的响应中获取动态内容并在后续其他请求中使用,常用的提取器类型有:
-
正则表达式提取器:使用正则表达式匹配的方式从响应中获取数据
-
JSON提取器:使用JsonPath从响应中获取数据
9.1,正则表达式提取器
1)添加正则表达式提取器:在TCP取样器右键 → 添加 → 后置处理器 → 正则表达式提取器
2)核心属性:
①名称:正则表达式提取器名称,任意
②Apply to:正则表达式提取器应用于何处,一般使用默认即可
③要检查的响应字段:从何处提取数据,一般使用主体(body)即可
-
Body(主体):从请求体中获取数据
-
Body (unescaped):所有html转义字符都被替换后的响应体。需要注意的是,jmeter不会根据上下文处理html转义字符,所以可能会有不正确替换,另外,该选项很影响性能,仅在绝对必要并且意识到其影响的情况下使用。
-
Body as a Document:通过Apache Tika,从各种类型的文档中提取文本。注意,该选项很影响性能
-
Response Headers(信息头):响应头,可能不适合非HTTP sample
-
Request Headers:请求头,可能不适用非HTTP sample
-
URL:从URL中获取数据
-
Response Code(响应代码):响应状态码,比如 200
-
Response Message(响应信息):响应消息,比如 OK
④引用名称:提取出数据后,存放到上下文的变量名,后续请求可以使用${变量名}
的方式引用
⑤正则表达式:提取数据的正则表达式,常用的正则表达式有:
-
提取全部:
^(.*)$
-
提取中间某一段:
(.*?) 或(.+?)
- 说明:
(.+?)
和(.*?)
的区别:
(.+?)
提取1个字符串及以上,不要太贪婪,在找到第一个匹配项后停止;
(.*?)
提取0个字符串及以上,要取的值是空值的时候可以取得到。
- 说明:
-
从中间某处提取到末尾:
([^"]+)
-
转义:
\
-
换行:
\n
⑥模板:如果正则表达式有多个提取结果,则结果是数组形式,模板$1$
、$2$
等,表示把解析到的第几个值赋给变量,并且从1开始匹配,一般情况使用$1$
即可。
-
$1$
表示 group1 -
$2$
表示 group2 -
$0$
表示整个匹配的整个表达式
⑦匹配数字(0代表随机):正则表达式匹配数据的结果可以看作一个数组,表示如何取值,一般使用1即可。
-
0代表随机取值
-
-1代表全部取值
-
大于0的正数N-表示选择第N个匹配的值(1表示取第一个值)
⑧缺省值:获取不到数据时的默认值
⑨使用空默认:获取不到数据时为空
3)配置案例:
涵义:在响应体中提取"KHQYBH":"
至"
中间的数据(当存在多个时,只取第一个),将提取出的数据存放到key为TQ_KHQYBH
的值中,以便后续接口使用
9.2,JSON提取器
1)添加JSON提取器:在TCP取样器右键 → 添加 → 后置处理器 → JSON提取器
2)核心属性:
①名称:JSON提取器名称,任意
②Apply to:正则表达式提取器应用于何处,一般使用默认即可
③Name of created variables:提取出数据后,存放到上下文的变量名,后续请求可以使用${变量名}
的方式引用
③JSON path expressions:JsonPath表达式
④Match No.(0 for Random):0 代表随机取值,n取第几个匹配值,-1匹配所有,后续引用时采用 变量名_N 取指定的第N个值
⑤Compute concatenation var(suffix_ALL):勾选此项后,如果匹配到多个结果,JMeter会使用,将他们连接起来,存储在的变量中,会自动命名为_ALL
⑥Default Values:缺省值,当JSONPath表达式未匹配到值时取该值
3)配置案例:
涵义:在响应体中获取JSON报文,转为JSON对象,获取其下一级key为Body的JSON对象,在获取其key为signList的JSON数组中的所有JSON对象,获取JSON对象中key为signNo的值,取第一个
注意:适用于响应报文为完整的JSON对象或JSON数组格式的接口,如果不是JSON格式会产生报错,常见于TCP请求中,响应报文会拼接上报文长度
10,前置处理器
1)作用:可以在发送请求前做一些特殊处理,如在TCP接口在请求前动态拼接报文长度、增加一些默认的参数等,常用的前置处理器有JSR223 PreProcessor、BeanShell PreProcessor等,本文以JSR223 PreProcessor为例,使用groovy语言在TCP接口在请求前动态拼接报文长度
2)添加前置处理器:在线程组右键 → 添加 → 前置处理器 → JSR223 PreProcessor
3)核心属性:
①名称:JSR223前置处理器提取器名称,任意
②脚本:编写符合脚本语言的代码
4)配置案例:
5)脚本:
// 脚本适用于 TCPSampler ,给报文体自动加8位报文头长度,且报文字符编码为 UTF-8
// JMeter 默认使用平台的默认字符值: Charset.defaultCharset().name(), 一般为GBK
// 若传递报文的字符编码不是UTF-8,为GBK,则不需求转为字符集
import java.nio.charset.StandardCharsets;
import org.apache.jmeter.protocol.tcp.sampler.TCPSampler;
def sampler = ctx.getCurrentSampler();
if(sampler instanceof TCPSampler) {
def text_encoding = "UTF-8";
def data = sampler.getRequestData();
data = data.replaceAll("[\\n\\r\\s]", "");
def new_bytes ;
def new_data ;
if(text_encoding == "UTF-8") {
// 设置tcp发送时,字符集的编码: UTF-8
props.put("tcp.charset", StandardCharsets.UTF_8.toString());
new_bytes = data.getBytes(StandardCharsets.UTF_8);
new_data = new String(new_bytes, StandardCharsets.UTF_8);
} else {
// 报文字符编码不为 UTF-8时
new_bytes = data.getBytes();
new_data = data;
}
// 计算报文头长度
def len = String.format("%08d", new_bytes.length);
// 拼接并更新TCPSampler的报文内容
sampler.setRequestData(len + new_data);
}
11,逻辑控制器
1)作用:正常情况下,一个线程组下配置多个取样器时,先请求的取样的的结果不影响后请求的取样器,但是某些场景下,我们需要前一个取样器成功再去请求后一个取样器;或者前一个接口请求一次,后续接口请求n次,类似于登录接口和业务接口;这些场景可以使用逻辑控制器模拟实现
2)添加IF控制器:在线程组右键 → 添加 → 逻辑控制器 → IF控制器
3)核心属性:
①名称:IF控制器名称,任意
②Expression (must evaluate to true or false):表达式,结果必须是true或false
4)配置案例:
涵义:当前Jmeter线程中最后一个取样器的结果是成功的,再执行其下的P0650001A13-代发工资文件通知接口
接口
12,监听器
1)作用:对压测结果进行统计
2)添加监听器:在线程组右键 → 添加 → 监听器
3)常用监听器:
- 查看结果树:用于查看每次调用接口的结果,可以在其中查看请求及响应报文
- 聚合报告:汇总所有的请求结果,并以表格的形式显示每个请求的统计信息,如请求的平均响应时间、最小响应时间、最大响应时间、请求次数、吞吐量等。
- 汇总报告:与聚合报告类似,提供对请求统计数据的汇总,显示请求的平均响应时间、最小和最大响应时间、吞吐量等。
三,HTTP接口压测案例
HTTP接口压测脚本配置基本类似于TCP,组件大部分能够通用,特色的组件主要有HTTP请求默认值、HTTP信息头管理器、HTTP请求等
1,HTTP请求默认值
1)作用:类似于TCP取样器配置,可以对要配置的HTTP请求做一个默认配置,如协议、IP、端口、编码、超时时间等,当一个线程组下配置了多个HTTP取样器(接口)时,如取样器不配置信息,则取HTTP请求默认值中的默认值,如有自定义配置,则取自定义配置
2)添加HTTP请求默认值:在线程组右键 → 添加 → 配置元件 → HTTP请求默认值
涵义:HTTP请求即用于模拟HTTP请求的取样器
3)核心属性:
略
4)配置案例:
2,HTTP信息头管理器
1)作用:为HTTP请求添加请求头信息,常用的如Content-Type等
2)添加HTTP请求默认值:在线程组或HTTP请求右键 → 添加 → 配置元件 → HTTP信息头管理器
3)核心属性:
略
4)配置案例:
3,HTTP请求
1)作用:类似于TCP取样器,在压测时,作为对应后端具体某一只HTTP接口的客户端
2)添加HTTP请求:在线程组右键 → 添加 → 取样器 → HTTP请求
3)核心属性:
略
4)配置案例:
注意:请求方式参数(Form表单数据)
和消息体数据(请求体)
只能选其一,在其中一个填写请求数据后,另一个选项卡点击会没有反应
四,其他
1,内置函数
Jmeter内置函数可以帮助我们处理数据,其种类繁多,如格式化日志函数、字符串拆分函数,随机函数等等,我们可以使用函数助手帮助我们查看并使用,以时间函数为例,当我们想生成一个当前日期+时间的字符串,以用于生成流水号时:
-
打开函数助手:
-
选择
time
函数: -
输入表达式求值的值为
yyyyMMddHHmmss
,点击生成,查看生成的结果是否满足需求:
-
如果满足需求,选中完整的函数表达式拷贝,在需要处粘贴即可:
2,日志
当我们在调试脚本时,有时需要通过日志查看接口的响应参数,或当前线程上下文中的信息,以便验证我们编写的脚本的正确性,我们可以打开Jmeter日志,结合后置处理器BeanShell PostProcessor打印日志进行查看
-
打开Jemter日志:
-
添加BeanShell 后置处理程序:
-
编写BeanShell 后置处理程序,打印从响应报文中使用提取器获取的字段:
3,启用禁用
我们可以通过启用/禁用功能,控制我们编写的组件是否加入测试流程,从而方便快捷的调整我们的测试方案,以刚的编写BeanShell 后置处理程序为例,操作流程:
-
在已启用的组件上右键,选择禁用:
-
组件置灰,则表示已禁用:
-
在已禁用的组件上右键,选择启用,即可重新启用组件: