目录
7、Http常见请求/响应头content-type内容类型讲解
# Test and Report informations
# APDEX(Application performance Index)
# Response Times
一、Http基础协议和解析
1、浏览器的B/S架构和C/S架构
(1)CS架构
(2)BS架构
(3)URL理解
URL为统一资源定位符,获取服务器资源的一种,标准格式如下:(http默认端口80;https默认端口443)
协议://服务器IP:端口/路径1/路径N?key1=value1&key2=value2
URL格式拆分描述:
- 协议:不同的协议有不同的解析方式
- 服务器ip:网络中存在无数的主机,要访问哪一台,通过公网ip区分
- 端口:一台主机上运行着很多的进程,为了区分不同进程,一个端口对应一个进程,http默认端口为80,https默认端口为443
- 路径:资源N多种,为了更进一步区分资源所在的路径(后端接口,一般称为“接口路径”,“接口”)
2、Http超文本传输协议
(1)含义
# 协议
协议是一种约定,规定好一种信息的格式,如果发送方按照这种请求格式发送信息,那么接收端就要按照这样的格式解析数据,这就是协议
# json协议
{
"name":"jack",
"age":23
}
# xml协议
<user>
<name> jack </name>
<age> 234 </age>
<pwd> 2342423</pwd>
</user>
(2)http协议
http协议即超文本传送协议(Hypertext Transfer Protocol),是Web联网的基础,也是手机PC联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,从建立连接到关闭连接的过程称为“一次连接”
HTTP请求-HTTP响应
响应码:
- 1xx:信息
- 2xx:成功 200 OK,请求正常
- 3xx:重定向
- 4xx:客户端错误 404 Not Found 服务器无法找到被请求的页面
- 5xx:服务器错误 503 Service Unavailable,服务器挂了或者不可用
(3)发展历史
http0.9-》http1.0-》http1.1-》http2.0,不多优化协议,增加更多功能
(4)和https的关系
Hyper Text Transfer Protocol over SecureSocket Layer主要由两部分组成:HTTP + SSL / TLS,比 HTTP 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性,增加破解成本
缺点:相同网络环境下,HTTPS 协议会使页面的加载时间延长近 50%,增加额外的计算资源消耗,增加 10%到 20%的耗电等;不过利大于弊,所以Https是趋势,相关资源损耗也在持续下降
如果做软件压测:直接压测内网ip,通过压测公网域名,不管是http还是https,都会带来额外的损耗而导致结果不准确
3、Http消息体拆分
(1)Http请求消息结构
# 请求行
- 请求方法
- URL地址
- 协议名
# 请求头
- 报文头包含若干个属性 格式为“属性名:属性值”,
- 服务端据此获取客户端的基本信息
# 请求体
请求的参数,可以是json对象,也可以是前端表单生成的key=value&key=value的字符串
(2)Http响应消息结构
# 响应行
报文协议及版本、状态码
# 响应头
报文头包含若干个属性 格式为“属性名:属性值”
# 响应正文
响应报文体,我们需要的内容,多种形式比如html、json、图片、视频文件等
4、HTTP的九种请求方法和响应码介绍
(1)浏览器请求方法
http1.0定义了三种:
- GET:向服务器获取资源,比如常见的查询请求
- POST:向服务器提交数据而发送的请求
- Head:和get类似,返回的响应中没有具体的内容,用于获取报头
http1.1定义了六种
- PUT:一般是用于更新请求,比如更新个人信息、商品信息全量更新
- PATCH:PUT 方法的补充,更新指定资源的部分数据
- DELETE:用于删除指定的资源
- OPTIONS:获取服务器支持的HTTP请求方法,服务器性能、跨域检查等
- CONNECT:方法的作用就是把服务器作为跳板,让服务器代替用户去访问其它网页,之后把数据原原本本的返回给用户,网页开发基本不用这个方法,如果是http代理就会使用这个,让服务器代理用户去访问其他网页,类似中介
- TRACE:回复服务器收到的请求,主要用于测试或诊断
(2)Http响应码
浏览器向服务器请求时,服务端响应的消息头里面有状态码,表示请求结果的状态
具体分类有:
1XX:收到请求,需要请求者继续执行操作,比较少用
2XX:请求成功,常用的 200
3XX:重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(好处:网站改版、域名迁移等,多个域名指向同个主站导流)
- 301:永久性跳转,比如域名过期,换个域名
- 302:临时性跳转
4XX:客户端出错,请求包含语法错误或者无法完成请求
- 400:请求出错,比如语法协议
- 403:没权限访问
- 404:找不到这个路径对应的接口或者文件
- 405:不允许此方法进行提交,Method not allowed,比如接口一定要POST方式,而你是用了GET
5XX:服务端出错,服务器在处理请求的过程中发生了错误
- 500:服务器内部报错了,完成不了这次请求
- 503:服务器宕机
5、Http请求头知识点讲解
http请求分为三部分:请求行,请求头, 请求体
(1)请求头
报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的基本信息
(2)常见请求头
Accept:浏览器支持的 MIME 媒体类型,比如 text/html,application/json,image/webp,/ 等
Accept-Encoding:浏览器发给服务器,声明浏览器支持的编码类型,gzip, deflate
Accept-Language:客户端接收的语言格式,比如 zh-CN
Connection:keep-alive,开启HTTP持久连接
Host:服务器的域名
Origin:告诉服务器请求从哪里发起的,仅包括协议和域名, CORS跨域请求中可以看到response有对应的header,Access-Control-Allow-Origin
Referer:告诉服务器请求的原始资源的URI,其用于所有类型的请求,并且包括:协议+域名+查询参数; 很多抢购服务会用这个做限制
User-Agent:服务器通过这个请求头判断用户的软件的应用类型、操作系统、软件开发商以及版本号、浏览器内核信息等; 风控系统、反作弊系统、反爬虫系统等基本会采集这类信息做参考
Cookie:表示服务端给客户端传的http请求状态,也是多个key=value形式组合,比如登录后的令牌等
Content-Type:HTTP请求提交的内容类型,post提交时才需要设置,比如文件上传,表单提交、json等
- form表单提交:application/x-www-form-urlencoded
- json方式提交:application/json
6、Http响应头知识点讲解
(1)响应头
报文头包含若干个属性 格式为“属性名:属性值”
(2)常见的响应头
- Allow:服务器支持哪些请求方法
- Content-Length:响应体的字节长度
- Content-Type:响应体的MIME类型
- Content-Encoding:设置数据使用的编码类型
- Date:设置消息发送的日期和时间
- Expires:设置响应体的过期时间,一个GMT时间,表示该缓存的有效时间
- cache-control:Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据,优先级高于Expires,控制粒度更细,如max-age=240,即4分钟
- Location:表示客户应当到哪里去获取资源,一般同时设置状态代码为3xx
- Server:服务器名称
- Transfer-Encoding:chunked 表示输出的内容长度不能确定,静态网页一般没有,基本出现在动态网页里面
- Access-Control-Allow-Origin:规定哪些站点可以参与跨站资源共享
7、Http常见请求/响应头content-type内容类型讲解
(1)Content-type理解
用来指定不同格式的请求响应信息,俗称 MIME媒体类型
(2)常见的取值
- text/html :HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
- application/json:JSON数据格式
- application/pdf :pdf格式
- application/octet-stream :二进制流数据,一般是文件下载
- application/x-www-form-urlencoded:form表单默认的提交数据的格式,会编码成key=value格式
- multipart/form-data: 表单中需要上传文件的文件格式类型
Http知识加深文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP
二、性能测试工具Jmeter和接口环境准备
1、性能测试分类和常见工具
(1)性能测试分类
# 性能测试
- 对系统不断施压,验证系统在资源范围内【是否达到性能指标】
- 通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试
# 压力测试
- 超过安全负载后对系统不断施压,直到系统崩溃,得出【系统最大承受能力】
- 通过在一定的负荷条件下,长时间连续运行系统给系统性能造成的影响
# 负载测试
对系统不断施压,当1项以上指标达到临界值后继续加压,看【系统处理能力变化】
# 稳定性测试
确定软硬件配置情况下,对系统分配一定的业务压力运行一段时间,检查【系统是否稳定】
(2)常见工具
# LoadRunner
性能稳定,压测结果及细粒度大,可以自定义脚本进行压测,但是太过于重大,功能比较繁多
# Apache AB(单接口压测最方便)
模拟多线程并发请求,ab命令对发出负载的计算机要求很低,既不会占用很多CPU,也不会占用太多的内存,但却会给目标服务器造成巨大的负载、简单DDOS攻击等
# Webbench
webbench首先fork出多个子进程,每个子进程都循环做web访问测试,子进程把访问的结果通过pipe告诉父进程,父进程做最终的统计结果
# Jmeter (GUI )
开源免费,功能强大,在互联网公司普遍使用
可以压测不同的协议和应用
- Web - HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, …)
- FTP
- Database via JDBC
- Message-oriented middleware (MOM) via JMS
- Mail - SMTP(S), POP3(S) and IMAP(S)
- TCP等等
Jmeter 使用场景如下:
- 功能测试
- 压力测试
- 分布式压力测试
- 纯java开发
Jmeter 优点如下:
- 上手容易,高性能
- 提供测试数据分析
- 各种报表数据图形展示
2、Jmeter基本介绍和使用场景
(1)什么是Jmeter
Jmeter 是 apache 公司基于 java 开发的一款开源性能测试工具
(2)Jmeter官网地址
官网地址: Apache JMeter - Apache JMeter™
(3)特点
开源免费功能强大,在互联网公司普遍使用
可以压测不同的协议和应用,如下:
- Web - HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, …)
- FTP
- Database via JDBC
- Message-oriented middleware (MOM) via JMS
- Mail - SMTP(S), POP3(S) and IMAP(S)
(3)使用场景及优点
- 支持功能测试、单机和分布式压力测试
- 纯java开发
- 上手容易,高性能
- 提供测试数据分析
- 各种报表数据图形展示
(4)缺点
不支持html、js渲染操作,不能做UI功能测试
(5)注意点
- JMeter 不是浏览器,它在协议级别工作
- 对于 Web 服务和远程服务而言,JMeter 看起来像一个浏览器
- JMeter 并不执行浏览器支持的所有操作,不像浏览器那样呈现 HTML 页面,不执行 HTML 页面中的 JS
3、多环境快速安装Jmeter5.x和汉化
(1)安装
安装过程参考文章:Jmeter的安装及环境部署【图文详细】_jmeter安装教程以及jdk环境配置-CSDN博客
(2)Jmeter目录
bin:核心可执行文件,包含配置
jmeter.bat: windows启动文件(window系统一定要配置显示文件拓展名)
jmeter: mac或者linux启动文件
jmeter-server:mac或者Liunx分布式压测使用的启动文件
jmeter-server.bat:window分布式压测使用的启动文件
jmeter.properties: 核心配置文件
extras:插件拓展的包
lib:核心的依赖包
(3)Jmeter语言版本中英文切换
# 临时切换
控制台修改 menu -> options -> choose language
# 永久切换
直接在配置文件中修改
bin目录 -> jmeter.properties,默认 #language=en,改为 language=zh_CN
4、后端HTTP接口允许环境和部署实战
(1)后端接口
公司里面多数都是前后端分离,项目启动后开发人员应该先定义接口文档,测试人员应该尽早拿到接口文档进行编写测试用例
接口文档获取:
- 老旧系统:找上司或者接手的开发人员进行获取;实在没法就只能抓包
- 如果里面参数涉及复杂的加密逻辑且开发人员不能协助,那就无法测试
- 新系统:找开发人员先定义接口,按照流程规范走,找技术负责人协调
我这里用的一个后端程序,直接本地启动运行了
命令行进入程序所在路径启动:java -jar 文件名
(2)后端接口说明
端口 8080
接口介绍 | 接口路径 | 参数和备注 | method |
商品列表 | /api/v1/product/list | 不用参数 | get |
登录接口 | /api/v1/user/login | {"mail":"794666918@qq.com","pwd":"123456"} | post |
用户信息 | /api/v1/user/info | 需要登录,http的header里面加入token字段 | get |
秒杀接口 | /api/v1/product/second_kill | 不用参数,用于测试接口耗时情况 | get |
商品详情 | /api/v1/product/detail | 用于可变参数压测,参数: id 和 title | get |
注意
- 登录账号密码,程序里面只提供一个,所以需要按照上面进行操作
- 常规就是get、post压测,1个接口到100个接口都类似
- 启动程序不能关闭,是运行程序
5、Jmeter5.X基础功能组件+线程组和Sampler
(1)线程组
线程组就是一组线程,并发执行,每个线程可以认为是一个请求
(2)添加线程组
添加->threads->线程组(控制总体并发)
线程属性:
- 线程数:虚拟用户数,一个虚拟用户占用一个进程或线程
- 准备时长(Ramp-Up Period(in seconds)):全部线程启动的时长,比如100个线程,20秒,则表示20秒内100个线程都要启动完成,每秒启动5个线程
- 循环次数:每个线程发送的次数,假如值为5,100个线程,则会发送500次请求,可以勾选永远循环
(3)添加Http
线程组->添加-> Sampler(取样器) -> Http请求 (一个线程组下面可以增加几个Sampler)
# 名称:采样器名称
# 注释:对这个采样器的描述
# web服务器:
- 默认协议是http
- 默认端口是80
- 服务器名称或IP :请求的目标服务器名称或IP地址
# 路径:服务器URL
(4)查看测试结果
线程组->添加->监听器->察看结果树
线程组->添加->监听器->聚合报告
位置:
- 放在http采集器级别,获取兄弟节点数据
- 放在http采样器下面,获取当前http采样器数据
6、Jmeter第一个性能测试接口
(1)目标
打开Jmeter压测http的get接口(商品列表)
新建一个商品模块的线程组,线程组下新增http请求,并对该请求添加结果树和聚合报告
(2)查看结果树
注意:查看结果树时,若出现乱码问题,解决办法如下:
Jmeter的bin目录下,找到jmeter.properties文件,修改配置后重启
#sampleresult.default.encoding=ISO-8859-1的注释去掉
改成:sampleresult.default.encoding=UTF-8
7、线程组setUP-tearDown和调度器
(1)线程组分类
- setUP:最先执行,前置工作
- 线程组:中级执行,常规处理
- tearDown:最后执行,收尾工作
(2)线程组调度器
调度器默认不勾选,调度器在勾选永远时一起使用,可以限制永久执行的持续时间,也可以限制启动延迟
(3)实例
配置各线程组以及结果树,查看对应接口执行顺序:setUP > 线程组 > tearDown
8、Http采样器复用和Http请求头管理
(1)Http请求默认值
需求:
如果有多个接口,每个接口都需要重复配置http协议、ip、端口等相同参数,维护起来麻烦,可以通过配置【 http请求默认值 】进行默认配置,那么对应的线程组则不用重复配置
(2)Http请求头管理
POST请求时,默认Content-Type为 text/plain格式,与实际请求参数不符合,需要设置请求头,可以通过【 HTTP信息头管理器 】进行设置
Content-Type: application/json
三、Jmeter聚合报告分析和多案例断言
1、压测结果聚合报告分析
(1)性能测试关键点
TPS:Transactions Per Second 每秒事务数,可以是一个接口、多个接口、一个业务流程,包括增删改操作
QPS:Queries Per Second, 每秒查询数,指一台服务器每秒能够响应的查询次数。QPS 只是一个简单查询的统计,不能描述增删改等操作,如果只是查询操作,那么TPS = QPS
RT:响应时间
(2)新增聚合报告
线程组->添加->监听器->聚合报告(Aggregate Report)
(3)参数配置
5000线程数,20秒持续压测
8000线程数,20秒持续压测
(4)得出最佳性能指标
5000线程 和 8000线程,5000线程每次增加300个线程,持续压测后得出最佳的吞吐量,此时线程数就是最佳
(5)各参数解读
- lable: sampler的名称
- Samples: 一共发出去多少请求,例如10个用户,循环10次,则是 100
- Average: 平均响应时间
- Median: 中位数,也就是 50% 用户的响应时间
- 90% Line : 90% 用户的响应不会超过该时间
- 95% Line : 95% 用户的响应不会超过该时间
- 99% Line : 99% 用户的响应不会超过该时间
- min : 最小响应时间
- max : 最大响应时间
- Error%:错误的请求的数量/请求的总数
- Throughput:吞吐量——默认情况下表示每秒完成的请求数(Request per Second) 可类比为qps
- KB/Sec: 每秒接收数据量
2、压测结果之响应断言
(1)断言理解
指期望用户指定的条件满足,当用户定义的约束条件不满足时会触发异常,简单来说,就是判断程序结果是否符合预期
应用断言的情况:
- 多数情况都可以,但是推荐使用较为简单的断言,比如响应断言
- 复杂断言会消耗压测机器的性能
(2)增加断言
线程组 -> 添加 -> 断言 -> 响应断言
(3)断言测试字段
- 响应文本 Text response: 响应服务器返回的文本内容
- 响应代码 Response Code: 断言Http 响应码是否符合预期,比如 200
- 响应消息 Response Message : 验证响应消息是否按预期显示
- 响应标头 Response Headers : 断言查看特定的 HTTP 标头是否存在
- 文档(文本)Document (text): 基本不用,高负载可能会占用大量内存导致OOM
- URL样例 URL Sampled : 针对请求的 URL 使用以确保它符合预期
(4)断言模式匹配规则
- 包括 Contains: 响应内容【包含】需要匹配,支持正则表达式
- 匹配 Matches: 响应内容要【完全匹配】需要匹配代表响应成功,大小写不敏感,支持正则表达式
- 相等 Equals: 响应内容要【完全等于】需要匹配代表响应成功,大小写敏感,内容是字符串
- 字符串Substring: 响应内容【包含需要匹配】的内容才代表响应成功,大小写敏感,内容是字符串
- 不相等 Not: 取反操作,不相等
- OR: 应用 OR 组合中的每个断言,将多个断言模式进行OR连接
(5)实例
这里以商品列表接口为例,使用错误的状态码来测试断言情况,比如:状态码为302才视为成功,否则给出“状态码不符合要求”的提示,返回报错
3、高并发业务下Jmeter压测之断言持续时间
(1)断言持续时间
断言持续时间用于判断服务器的响应时间,作用对象是服务器
Duration in milliseconds:响应时间设置(单位毫秒),如果响应时间大于设置的响应时间,断言失败,否则成功
(2)应用场景
高并发下,接口响应时间增加,如果超过一定时间则认为是超时
注意:
断言类型很多,常规Duration Assertion与Response Assertion基本就足够使用了
常规业务里面会有状态码断言,还有RT响应时间要求,这样的话聚合报告的异常错误率就会更满足业务需求
四、CSV可变参数实战和标准压测流程
1、Jmeter用户自定义变量
(1)需求背景
企业开发里面一般都是有多环境开发,项目中有变量会根据环境变化而变化
(2)解决方式
可以使用自定义变量,在一处定义四处使用,改的时候只要改一次即可
线程组->add -> Config Element(配置原件)-> User Definde Variable(用户定义的变量)
(3)实例
以商品列表接口为例,我们之前配置了Http请求默认值,配置http协议、ip、端口等,这里的ip和端口号具象化配置,实际会有多环境进行开发,则需要重复修改ip以及端口
这里可以使用【用户定义的变量】直接以变量形式展示ip和端口
- 引用方式${XXX},在接口的变量中使用
观察结果树,可看到商品列表接口请求成功
2、CSV多个可变参数压测
(1)需求背景
业务开发里面参数一般不是固定方式,而是采用可变参数进行压测,比如压测商品详情,查看id从1~100 的商品详情
(2)解决方案-CSV可变参数
# 添加CSV可变参数
线程组—>添加—>配置原件—>CSV Data Set Config
# 新建test.csv文件
我们需要提前准备好一批id, 直接使用jmeter压测
注意:csv文件用【,】分隔符;txt文件用【||】分隔符
# CSV参数读取配置
新增CSV可变参数,配置CSV数据文件,相关参数如下:
# 请求应用
配置完成CSV可变参数后,在商品详情接口处设置参数来引用在CSV可变参数处设置的变量名称
点击运行后查看结果树,可以看到请求成功
3、高并发业务下Jmeter集合点
(1)性能测试
性能测试是多用户并发测试,但真正的并发其实是不存在的,需要用工具模拟并发。我们前面的测试“线程数”是并发用户数,启动需要时间,不是并发同一时刻访问,常规压测需要模拟全部用户同一时刻访问,比如【秒杀】案例场景
需求:让全部请求同时集合在一起,然后再一起访问,实现真正的并发
(2)解决方式-Jmeter的同步定时器
右键HTTP请求->添加->定时器->同步定时器
- 将多个请求同步并发操作,同步定时器又可称之为“集合点”
- 将需要做并发的请求集合在一起后再进行请求
注意事项:
- 模拟用户组数量设置的值不能大于线程组数量,最好的情况是 【线程组】 可以被 【用户组】整除
- 超时时间以毫秒为单位:指定人数 多少毫秒没有到达集合点则算超时(超时时间是0则无限等待,如果是大于0,则未达到集合的【用户组】数量,会在超时后执行)
五、BeanShell实战
1、BeanShell作用
(1)BeanShell理解
- 用Java写成的小型、免费的Java源代码解释器
- 可以执行标准Java语句和表达式,完全符合java语法的java脚本语言
- 包括一些脚本命令,有自己的一些语法和方法,是一种松散类型的脚本语言
- 用于一些复杂的个性化需求,使用更灵活,功能更强大
(2)使用场景
-
需要在jmeter里面对数据进行二次处理,定制自己的业务逻辑(对参数进行加密、base64编码、时间格式化、文件操作、自定义断言等)
-
属于Jmeter二次开发
注意:Jmeter里面需要开启【日志查看】方便调试
(3)常用分类
- 采样器BeanShell
- 前置处理器 BeanShell PreProcessor:提前对参数处理比如加密编码
- 后置处理器 BeanShell PostProcessor :对返回结果做处理
- 断言 BeanShell Assert :验证请求接口是否满足要求
(4)内置对象
BeanShell内置对象如下,可以直接使用
SampleResult, ResponseCode, ResponseMessage, IsSuccess, Label, FileName, ctx, vars, props, log
2、BeanShell开发核心知识点
(1)BeanShell取样器
# 对变量操作
使用Bean shell内置对象 vars 对【变量】进行存取操作,作用在当前线程组,类似java里面的map
vars.put("name","jack");//数据存到jmeter变量中
vars.get("name"); //从jmeter中获得变量值
# 对属性操作
使用Bean shell内置对象 props 对【属性】进行存取操作,作用在跨线程组使用
props.get("language"); //jmeter.properties里面定义的属性
props.put("language","zh_CN");
示例:在发起请求前,使用BeanShell采样器设置变量值以及获取language属性
使用内置对象vars 获取变量的值,在HTTP请求中可调用这里的变量,方便排查,我们也可在info日志中打印对应变量的值
vars.put("title","javase课程");
vars.put("id","8888");
String title = vars.get("title");
log.info("title="+title);
String lang = props.get("language");
log.info("lang="+lang);
(2)HTTP请求设置
定义HTTP请求参数,该请求需要传参,BeanShell取样器里面定义了变量[id、title],在这里直接读取对应变量
${id}、${title}
从结果树可以看到,我们在发起请求前设置的变量通过该接口返回了
3、BeanShell响应JSON处理和自定义断言
(1)需求
根据业务结果,自定义响应断言
(2)步骤
# 新建线程组以及HTTP请求
测试计划->添加->线程->线程组
线程组->添加->取样器->HTTP请求
这里还是应用商品详情接口做参考,具体接口信息见第二章第四节
# 新增BeanShell预处理程序
商品详情接口传两个参数,这里使用BeanShell预处理程序用vars定义入参,有些项目会有需要对参数进行加密,比如MD5,则可以如下操作
import org.apache.commons.codec.digest.DigestUtils;
String signs = DigestUtils.md5Hex("sdfsdfdsfds");
log.info("md5==="+signs);
//vars.put("pwd",signs)
vars.put("id","888888");
vars.put("title","Jmeter实践-自定义断言");
# 新增BeanShell断言
BeanShell断言可以拿到对应的响应结果[响应信息、响应码]
BeanShell断言的核心变量:
String data = prev.getResponseDataAsString() //获取响应信息
prev.getResponseCode() //获取响应code
Failure = false //表示断言成功
Failure = true //表示断言失败
通过上prev参数获取到的响应信息是一个字符串,如果要转换至json格式,需要使用JSON解析工具,即第三方jar包,jar包需要放入jmeter目录下的 \lib\ext 中,然后重启Jmeter
(更多api可参考文档:JSONObject (stleary.github.io))
BeanShell断言具体代码如下:
这里使用code为1做断言成功的示例,实际结果应该是code=0
import org.json.*;
String data = prev.getResponseDataAsString(); //获取响应信息
String httpCode = prev.getResponseCode(); //获取响应code
log.info("data="+data);
log.info("httpCode="+httpCode);
JSONObject jsonObj = new JSONObject(data);
log.info(jsonObj.toString());
int code = jsonObj.getInt("code");
if(code == 1){
Failure = false;
}else{
Failure = true;
FailureMessage = "这个断言失败啦,自定义beanshell";
}
查看结果树,可以看到该请求失败,具体断言响应结果如图
4、Jmeter压测post方式接口和关联接口场景
(1)需求
常规接口需要登录后才可以压测,我们这里使用接口关联进行压力测试
(2)案例操作
- 登录接口压测(post方式)
- 个人信息接口压测(get方式)
(3)实现
- 第一个接口:参数化批量请求接口,获取相关响应,提取数据保存文件,作为下个接口的入参
- 第二个接口:通过参数化,读取第一个接口的文件进行操作
(4)实际操作
# 登录接口
首先准备一批账号存取在csv文件中,命名为【account.csv】,使用CSV参数化,请求为POST格式时,一整行为一个变量,需要使用一个不存在的字符串(如||)来当作分隔符
从上图可得,用户登录接口登录成功后,会返回一条响应数据,我们需要提取其中的 data 值
HTTP请求->添加->后置处理器->BeanShell后置处理程序,具体代码如下:
import org.json.*;
//String responseCode = prev.getResponseCode();
String data = prev.getResponseDataAsString(); //获取响应信息
JSONObject jsonobj = new JSONObject(data); //转json对象
log.info(jsonobj.toString());
int code = jsonobj.getInt("code");
if(code == 0 ){
FileWriter fstream = new FileWriter("E:/Jmeter-Desktop/tokens.txt",true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(jsonobj.get("data")+"\n"); //向文件中写入data数据
out.close();
fstream.close();
}else{
}
写完后置处理内容后,对该内容进行测试,设置线程数为10,点击执行,执行完成后,可以看到tokens.txt文件中新增了10个token值
# 用户信息接口
对用户信息接口进行测试,将上面获取到的token值作为参数传入用户信息接口
在HTTP头信息管理器中传入变量 token ,通过CSV 数据文件设置将tokens.txt文件导入
先禁用登录接口,点击执行,可以查看结果树,用户信息接口执行成功
5、BeanShell使用外部Java文件
(1)需求
常规beanshell里面写代码,适合简单的逻辑,不过工作里面还会用到更多方法逻辑,需要在idea编辑器里面写,然后进行调用
比如:
- jar包:jar包需要放入jmeter目录下的 \lib\ext 中,然后重启Jmeter
- java文件
(2)步骤
使用 source加载源码,路径可以是绝对路径或相对路径,加载源文件后可以直接使用【类名.方法名(参数)】
source("E:/Jmeter-Desktop/CommonUtil.java");
String randomCode = CommonUtil.getRandomCode(4);
log.info("randomCode="+randomCode);
String uuid = CommonUtil.generateUUID();
log.info("uuid="+uuid);
【CommonUtil.java】完整代码如下:
import java.util.Random;
import java.util.UUID;
public class CommonUtil {
/**
* 获取验证码随机数
*
* @param length
* @return
*/
public static String getRandomCode(int length) {
String sources = "0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int j = 0; j < length; j++) {
sb.append(sources.charAt(random.nextInt(9)));
}
return sb.toString();
}
/**
* 生成uuid
*
* @return
*/
public static String generateUUID() {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
}
}
六、Jmeter性能测试之html可视化压测报告
1、Jmeter-html可视化压测报告
(1)测试报告
Jmeter自带的报告有聚合报告、汇总报告等,能够收集到性能数据,但显示比较单一,
-
Jmeter 可以生成 HTML 性能测试报告
(2)html可视化压测报告生成
步骤:
- 保存jmx到本地
- 进入到jmeter的bin目录下
- 摁住shift键后右键打开Powershell窗口
- 输入Jmeter命令生成报告
./jmeter -n -t E://JMX文件//report.jmx -l E://JMX文件//temp//jtl//result.jtl -e -o E://JMX文件//temp//result
参数说明:
- -n:非gui方式运行jmeter
- -t :jmx 脚本路径
- -l :result.jtl 运行结果保存路径,注意:.jtl 文件名不能重复,且文件夹需要存在
- -e :在脚本运行结束后生成 HTML 报告
- -o :用于存放 HTML 报告的目录,且文件夹需要存在
2、Jmeter压测生成多维度图形化HTML测试报告
(1)dashboard讲解
# Test and Report informations
- Source file:jtl文件名
- Start Time :压测开始时间
- End Time :压测结束时间
- Filter for display:过滤器
# APDEX(Application performance Index)
- apdex:应用程序性能指标,范围在0~1之间,1表示达到所有用户均满意
- T(Toleration threshold):可接受阀值
- F(Frustration threshold):失败阀值
- Lable:sampler采样器名称
# Requests Summary
- PASS:成功率
- FAIL:失败率
# Statistics 统计数据
- lable:sampler采样器名称
- samples:请求总数,并发数*循环次数
- FAIL:失败次数
- Error%:失败率
- Average:平均响应时间
- Min:最小响应时间
- Max:最大响应时间
- 90th pct:90%的用户响应时间不会超过这个值
- 95th pct:95%的用户响应时间不会超过这个值
- 99th pct:99%的用户响应时间不会超过这个值 (存在极端值)
- Transactions/s:Request per Second吞吐量 qps
- Received:每秒从服务器接收的数据量
- sent:每秒发送的数据量
(2)charts讲解
# Over Time(随着时间的变化)
- Response Times Over Time:响应时间变化趋势
- Response Time Percentiles Over Time (successful responses):最大,最小,平均,用户响应时间
- Active Threads Over Time:并发用户数趋势
- Bytes Throughput Over Time:每秒接收和请求字节数变化,蓝色表示发送,黄色表示接受
- Latencies Over Time:平均响应延时趋势
- Connect Time Over Time :连接耗时趋势
# Throughput
- Hits Per Second (excluding embedded resources):每秒点击次数
- Codes Per Second (excluding embedded resources):每秒状态码数量
- Transactions Per Second:即TPS,每秒事务数
- Response Time Vs Request:响应时间和请求数对比
- Latency Vs Request:延迟时间和请求数对比
# Response Times
- Response Time Percentiles:响应时间百分比
- Response Time Overview:响应时间概述
- Time Vs Threads:活跃线程数和响应时间
- Response Time Distribution:响应时间分布图
七、linux下非GUI压测
1、linux下非GUI压测实例需求和环境说明
(1)需求
常规图形下压测会影响相关性能指标,实际工作里面压测会在linux压测,才更加准确,性能测试后,会做部分轻量级性能优化提升吞吐量
(2)环境准备
-
两个接口的jmx脚本(集合点500并发,持续2分钟)
-
linux服务器(推荐使用阿里云服务器)
-
linux安装jdk8
(3)后端接口说明
端口 8080
接口介绍 | 接口路径 | 参数和备注 | method |
商品列表 | /api/v1/product/list | 不用参数 | get |
登录接口 | /api/v1/user/login | {"mail":"794666918@qq.com","pwd":"123456"} | post |
用户信息 | /api/v1/user/info | 需要登录,http的header里面加入token字段 | get |
秒杀接口 | /api/v1/product/second_kill | 不用参数,用于测试接口耗时情况 | get |
商品详情 | /api/v1/product/detail | 用于可变参数压测,参数: id 和 title | get |
2、Linux CentOS服务器安装JDK8环境
(1)安装JDK8环境
安装步骤见文章:Linux入门基础完整版【详解】_linux操作系统入门-CSDN博客,【第五章第四节】
(2)上传Jmeter安装包和jmx脚本
我将Jmeter安装包和jmx脚本放在 /home/local路径下,这里我使用的工作台是【FinalShell】,因此可以直接将包拖动上传
Jmeter安装包使用unzip解压即可
//解压缩
unzip apache-jmeter-5.5.zip
//重命名
mv apache-jmeter-5.5 jmeter
注意:如果unzip未安装,则使用【yum install unzip】命令进行安装
3、Linux服务器非GUI压测实战和报告下载
(1)上传应用程序
我们要对接口进行压测,那么对应的启动程序需要开启,这里直接上传对应的jar包
linux上的启动方式与windows一致,但是有一个问题,终端无法关闭
如果退出终端,也需要进程继续启动,则可以使用nohup命令
#守护进程的方式启动,退出终端,进程依旧运行
nohup java -jar xdclass-edu.jar &
(2)调整jvm内存
启动的时候可以调整jvm内存,方便后续性能优化对比
java -jar -Xms128m -Xmx128m -Xss228k xdclass-edu.jar
nohup java -jar -Xms128m -Xmx128m -Xss228k xdclass-edu.jar &
// Xms 堆内存初始大小
// Xmx 堆内存最大值
// xss 线程栈大小
(3)调整JMX脚本相关参数
- IP和端口
- 参数化路径
这里要修改的是对应的ip和端口,我程序启在了当前环境,因此不用修改
(4)执行压测
进到Jmeter目录下的bin目录,执行运行命令,注意:测试报告目录需要先创建好
./jmeter -n -t /home/local/linux_load_test.jmx -l /home/local/temp/jtl/result.jtl -e -o /home/local/temp/result
参数说明:
- -n:非gui方式运行jmeter
- -t :jmx 脚本路径
- -l :result.jtl 运行结果保存路径,注意:.jtl 文件名不能重复,且文件夹需要存在
- -e :在脚本运行结束后生成 HTML 报告
- -o :用于存放 HTML 报告的目录,且文件夹需要存在
(5)下载测试报告
打包完成后,result路径下即为生成的测试报告,直接下载即可