拿Tp90举例
接口A连续响应10次 | 请求序号 | 响应时间ms |
---|---|---|
1 | 800 | |
2 | 600 | |
3 | 500 | |
4 | 900 | |
5 | 950 | |
6 | 750 | |
7 | 400 | |
8 | 500 | |
9 | 300 | |
10 | 500 |
第一步:将列表降序排列
接口A连续响应10次 | 请求序号 | 响应时间ms |
---|---|---|
5 | 950 | |
4 | 900 | |
1 | 800 | |
6 | 750 | |
2 | 600 | |
3 | 500 | |
8 | 500 | |
10 | 500 | |
7 | 400 | |
9 | 300 |
90%*10=9,从倒数第一个到第九个都处于900ms以下,所以就以900ms为分界线
1、支持客户/服务器模式。
2、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、 POST、PUT、DELETE。每种方法规定了客户与服务器联系的类型不同。
由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4、无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到 客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5、无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态 意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。 另一方面,在服务器不需要先前信息时它的应答就较快。
关于压力测试、负载测试、性能测试概念区分的问题
1、对于上述三个概念,业界无统一标准和定义,资料五花八门,说的各不一样
2、对于初学者来说,可以先忽略这些概念
3、只需记住:所做的测试都成为性能测试,在实际公司里,都叫做【压测】
4、至于是为了测试最大并发用户、稳定性还是最高tps,这些都属于性能测试,只是测试的目的有所不同,因为目的不同而设计成不同的测试场景
官方网站:https://jmeter.apache.org/
1、本机配置好Java环境变量
2、官网下载压缩包,在任意目录下解压
3、修改配置文件,打开Jmeter的bin目录下jmeter.properties,修改
language=zh_CN #中英文环境
sampleresult.default.encoding=utf-8 #防止乱码
调整图标大小
jmeter.toolbar.icons.size=32x32
jmeter.tree.icons.size=32x32
修改消息体数据大小
jsyntaxtextarea.font.family= Hack
jsyntaxtextarea.font.size=36
改变界面元素大小
更改为 true ,才算启用
jmeter.hidpi.mode=true
控制大小
jmeter.hidpi.scale.factor=2.0
若修改配置未生效,则在jmeter.bat中增加如下代码
set JVM_ARGS=%JVM_ARGS% -Dswing.plaf.metal.controlFont=Dialog-20
set JVM_ARGS=%JVM_ARGS% -Dswing.plaf.metal.systemFont=Dialog-20
set JVM_ARGS=%JVM_ARGS% -Dswing.plaf.metal.userFont=SansSerif-20
set JVM_ARGS=%JVM_ARGS% -Dswing.plaf.metal.smallFont=SansSerif-20
4、进入到Jmeter的bin目录下,双击jmeter.bat启动
入参的三种类型
接口名称 | 接口类型 | 参数 |
---|---|---|
参数为key=value | POST | username=“123”&password=“123” |
参数为json类型 | POST | {username=“123”,password=“123”} |
参数为key=json类型 | POST | key = {username=“123”,password=“123”} |
第二种:json类型
json类型的入参都是填写在【消息体数据】中的,如果消息体数据有数据,则无法操作【参数】
注意:参数为json类型需增加一个http信息头管理的配置元件,还需要注意的是配置元件的生效域,不一定所有接口的入参都是这种类型
http信息头管理:
PS:报415的错,检查是否加了信息头
第三种:key=json类型
便捷方法:可从底部的【从剪贴板添加】直接粘贴
结果树中查看到的成功状态,仅为接口调用成功(因respond code=200),但不能判断业务是否跑通了,所以则需要加断言。
1、添加断言:
JSON路径表达式:$.code 代表JSON中的code字段名(详细参考:https://github.com/json-path/JsonPath)
需勾选additionally assert value、match as regular expression
PS:断言也注意断言文件存放的位置,存放的层级不同,生效域则不同,比如途中存放在登录接口下,仅对登录接口生效,若放置在最外层,则对全域生效
2、json中包含了数组,可按如下处理:
示例json:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
处理方式:
JsonPath | Result |
---|---|
$.store.book[*].author | The authors of all books |
$…author | All authors |
$.store.* | All things, both books and bicycles |
$.store…price | The price of everything |
$…book[2] | The third book |
$…book[-2] | The second to last book |
$…book[0,1] | The first two books |
$…book[:2] | All books from index 0 (inclusive) until index 2 (exclusive) |
$…book[1:2] | All books from index 1 (inclusive) until index 2 (exclusive) |
$…book[-2:] | Last two books |
$…book[2:] | All books from index 2 (inclusive) to last |
$…book[?(@.isbn)] | All books with an ISBN number |
$.store.book[?(@.price < 10)] | All books in store cheaper than 10 |
Misplaced @ |
$…book[?(@.price <= $[‘expensive’])] | All books in store that are not “expensive” |
| $…book[?(@.author =~ /.REES/i)] | All books matching regex (ignore case) |
| $… | Give me every thing |
| $…book.length() | The number of books |
Apply to:
测试字段:选择需要对哪个数据做判断
响应断言模式匹配规则:
定义全局变量,例如域名及端口号
接口中可通过${变量名称}配置
功能位置:工具栏倒数第二个
常用的函数例如:
输入完范围后,点击【生成】按钮,复制【当前JMeter变量】的语句,粘贴至【参数】的【值】中
点击【生成】按钮后,${__RandomString(8,abcdefghijklmQ39589fsafdgAAA,)} 函数字符串会自动复制到剪切板
两个参数皆为可选填,都不填也可,直接点击生成就可以直接用
填了参数
1、**CSVRead:**从文本文件中读取数据
优点:该函数适用于使用登录后,仍然需要用这些账号进行一系列操作的压测
第一个参数填文件的绝对路径,第二个参数填第几列,例如下图中:第一列是登录接口的用户名,第二列是密码
注意:接口轮询中使用txt文件中的用户数据数量,取决于线程数的数量
线程数=1时,无论循环次数为几,皆使用文件中的第一条用户数据
线程数=2时,调了两条txt中的用户数据
线程数=4时,重复调用了两遍文件中的两条数据
使用函数生成的参数来替换接口中的参数,如下图中的mobile、password字段
PS:存储函数的变量名
2、CSV Data Set Config
功能添加路径:线程组→添加→配置元件→CSV Data Set Config
文件编码:可以不填
如果接口中的参数是用西文逗号隔开的(例如:“user”:“username,password”),那么txt数据就不可以再用逗号隔开,可以用【\t】代替,在txt中为用tab键隔开,也可以用别的符号隔开
| Recycle on EOF(遇到文件结束符再次循环?) | Stop thread onEOF(遇到文件结束符停止线程?) | 参数效果 |
| — | — | — |
| True | False | 重复 |
| False | True | 唯一 |
参数效果=唯一 举例:txt有四条数据,线程数=2,循环次数=3,此时接口只会跑四次,取的txt中四条数据,第五条因需重头取,导致数据重复,所以不会继续运行
参数替换方式
注意:使用CSV Data Set Config读取数据,无论线程数与循环次数是几,每次查询都是查询下一条数据,若所有数据都读取了一遍,则会从头读取第二遍
线程数=1,循环次数=2时,会使用文件中的两条用户数据
假设txt中是四条用户数据,线程数=2,循环次数=2,在轮询时,会依次读取文件中的四条用户数据
线程数:假设有多少用户正在同时使用
多用户场景时,无需参考查看结果树中的接口顺序,其实是同时发生的
apply to:一般选main sample only (主请求)
Name of created values:对提取的变量起名
JSON Path expression:要提取的变量(用jsonpath写)
{
"responseStatus": {
},
"docGroups": [
{
"documents": [
{
"docId": 38604724,
"startTime": 1673406999
},
{
"docId": 2,
"startTime": 1673406998
}
],
"events": []
}
{
"responseStatus": {
},
"docGroups": [
{
"documents": [
{
"docId": 1,
"startTime": 1673406999
},
{
"docId": 2,
"startTime": 1673406998
}
],
"events": []
}
Match No:想提取第几个数据
若其他接口想调用取到的值,如下图catalogId字段一样使用即可
调试取样器可以打印出来Jmeter运行过程中保存下来的参数,需要配合查看结果树使用,无需配置任何数据
结果树中可看到获取到的get_docID值
可以通过正则表达式来获取http请求返回的数据
引用名称:匹配后的结果,保存到一个参数中,如param
正则表达式:
三步走:
1、拷贝目标数据和左右边界
2、把目标数据用括号括起来
3、把目标数据用.+?代替
模板:
1
1
1表示取匹配到的第一组数据,
2
2
2为第二组
匹配数字:当某组数据中包含多少个参数时,0代表随机,1代表该组的第一个参数,2表示第二 个。。。-1代表获取全部的参数,这个时候,引用名称就变成了参数数组,可以通过param_n来 获取指定的参数,当有多组数据时,第一组为param_1_g1,第二组为param_1_g2
结果:看倒数第四行的re_docid字段,是通过正则提取器提取到的第一个文章id
模拟用户使用时,循环次数要选【永久】
聚合报告结果:
#样本: 表示一共发出了多少个请求Average:平均响应时间
中位数:类似于50% Line90% Line: 假设该值为20,那么90%用户的响应时间小于等于20msMin:最小响应时间
Max/最大值: 最大响应时间
Error%/异常%: 错误率,出现错误的请求数量/请求的总数Throughput:吞吐量KB/Sec: 每秒从服务器端接收到的数据量
吞吐量:默认情况下表示每秒完成的请求数(Request per Second) 对于接口测试来说,Jmeter里的吞吐量=TPS
保存结果:聚合报告底部可保存结果数据
tip:
1、若两接口在同一线程组下,TPS值一致,但响应时间不一定一致
2、有关联关系的接口放在同一个线程组下,无关联的接口们需独立存放在不同的线程组下
1、Jmeter中的定时器类似于loadrunner中的pacing值和think_time
1)定时器是在每个sampler(采样器)之前执行的,而不是之后
2)定时器是有作用域的;当执行一个sampler之前时,所有当前作用域内的定时器都会被执行。且所有的sampler执行前都会执行定时器
3)如果希望定时器仅应用于其中一个sampler,则把该定时器作为子节点加入
2、常用的定时器
常用的逻辑控制器:
1、循环控制器:可以设置该控制器内的sampler执行的次数,循环次数与线程的循环次数各自独立
此条件下,【获取专栏详情页的资讯列表】接口仅执行1次,【请求2】接口执行会执行6次
2、if控制器:根据判断条件决定是否执行该控制器内的请求,如果是字符串比较条件,参数和字符串 都需要加引号
条件格式:
KaTeX parse error: Expected group after '_' at position 2: {_̲_jexl3(条件表达式)}<…{__jexl3(KaTeX parse error: Expected 'EOF', got '}' at position 11: {num} > 5)}̲、
2、若相比较的…{__jexl3(“${ip}”) == “xxxxx”)}
3、仅一次控制器:该控制器内的请求只执行一次,无论线程循环多少次
此种情况下本应【请求2】【请求3】皆执行6次,但因为【请求3】在【仅一次控制器】下,最终结果为:
【请求2】执行6次【请求3】执行1次
4、foreach控制器,可以遍历某个参数数组,循环获取数组中的参数
参数是通过其他接口通过提取器提取出来的参数数组,再把参数循环附入需要这些参数的接口
结束循环字段:${get_docId_matchNr}取字数组末尾的get_docId_matchNr=12,方便标记,也不会产生写死的情况(只能获取到get_docId_9的情况)
输入变量法前缀:取自于结果树中get_docId(名字是自己在提取器中设置的变量名)
cookie数据保存在客户端,session数据保存在服务器端。cookie有安全隐患,但是Session过多的时候会消耗服务器资源
Cookie 存在一定的全安隐患。Cookie 像我们以前用的存折,用户的存钱、取钱都会记录在这张存折上(即浏览器中会保存所有用户信息),那么对于有非分想法的人可能会去修改存折上的数据(这个比喻忽略掉银行同样会记录用户存取款的金额)。相对于存折,银行卡要全安的得多,客户拿到的只是一个银行卡号(即浏览器只保留一个 Sessionid),那么用户的存钱、取钱都会记录在银行的系统里(即服务器端),只得到一个 sessionid 是没有任何意义的,所以相对于 Cookie 来说就会安全很多。
cv文章~~
位置:
使用:
1、名称:取自抓包接口中cookie下,对应的cookie名称,具体其中哪个字段作为cookie需问开发
2、值:即对应的cookie值,配置的cookie必须是有效的,无效接口会有对应的提示:比如用户无效啊,用户未登录~之类的
3、域:接口的域名,全局配置的话,可用
i
p
对应的名称
写,配置如下图中,可写为
{ip对应的名称}写,配置如下图中,可写为
ip对应的名称写,配置如下图中,可写为{ip}
无需每次通过抓包获取cookie的便捷方法:
调用login接口获取cookie,http cookie管理器无需填写内容、接口中无需调用,管理器会自动获取接口中cookie塞到需要cookie的接口中
简单了解一下token的使用~
token知识~
从登录接口中提取token,若是在请求头里需要增加该参数,则在HTTP信息头管理器中添加对应的key、value
内容不全也无真实实例可展示(手头接口不支持)需要细了解请自行搜索
上传文件小点~:
1、文件上传原理:浏览器将本地文件内容通过HTTP发送到服务器,服务器收到数据后重新创建一个文件
2、文件上传的HTTP请求content-type:multipart/form-data,MIME类型为application/octet-stream
3、文件上传一般有表单上传和ajax上传两种方式
实现步骤:
1、需要用到的图片本地地址填在txt文本里
2、把需要读取的txt文件配置在【CSV数据文件设置】中
3、
下载:
1、文件下载的原理:服务器将文件内容通过HTTP发送到浏览器,浏览器接受到数据后在本地创建一个文件
2、创建文件是浏览器的自沈从文,测试文件下载不需要在本地创建文件
3、文件下载是一个普通的HTTP GET类型请求
1、接口配置为http请求
2、添加header:Content-Type:text/xml;chartset-
要发送的文本:可能是xml、也可能是十六进制的一串数据,具体数据格式需要找开发了解
1、添加数据库jar包
3、配置JDBC Connect Configuration
红框中为需要填写的参数;
Database URL:jdbc:mysql://{ip}:{port}/{dbname}?useUnicode=true&characterEncoding=utf8
JDBC Driver class:选择所需使用的数据库
4、**JDBC Request **
若想保存查询出的数据
1、添加【调试取样器】
2、【JDBC Request】中【Variable names】赋值
调试取样器中可查看到保存下来的结果
http://jmeter-plugins.org/downloads/all
1、下载jmeter-plugins.jar
2、把jar文件放入%Jmeter_Home%\lib\ext,重启jmeter
3、点击工具栏中的图标,可对插件进行管理
可能会用到的插件:
安装:
1、搜索并勾选需要的插件
2、点击并等待,下载完成后会自动重启