一、JMeter概述
1、性能测试采用的方法以及测试的阶段:

2、**什么是软件的性能:**软件执行功能的能力的度量。
3、什么是软件的性能测试:****模拟真实的(生产环境)下的业务压力量和使用场景,来测试软件的各种性能指标是否达到真实的性能需求。
4、性能测试的目的:
(1)验证(评估)软件系统的性能是否达标
(2)找到性能瓶颈—弱点
(3)系统调优—需要开发人员和运维人员合作完成
(4)测试软件稳定性和可靠性—是否能长时间稳定运行,提供可靠的服务
5、性能测试的应用场景:
(1)**用户量大:**爆发增长的用户、缓慢增加的用户
(2)使用频繁
(3)面临大数据量
(4)重要的功能
6、整个行业里软件测试团队的时间配比:
功能测试:性能测试=3:1
7、说明:专职的性能测试岗位较少,但是要求知识面更宽、薪资水平也更高。
二、性能测试的关注点
1、被测系统的组成:客户端、应用服务器、数据服务器、网络。
2、影响性能的因素:
(1)硬件:CPU、内存、磁盘
(2)操作系统:Linux常见
(3)网络:上行网速、下行网速
(4)中间件、应用服务器的配置
(5)数据库设计
(6)客户端
(7)编程语言、算法、架构
3、性能测试从三个方面测试:
(1)服务器端----重点!!!
(2)网络
(3)客户端
4、性能测试结果标准(性能指标的制定标准):性能好不好,取决于以下的各种条件
(1)多:支持的用户多
(2)快:响应速度快(时间短)
(3)好:稳定性好(能长期稳定运行)
(4)省:节省系统各项资源(CPU、内存、网络带宽、磁盘空间等)
5、测试人员从哪三个视角关注性能测试问题:
(1)用户视角:响应时间
(2)管理员视角:资源占用率、性能瓶颈、稳定性、最大用户数等。
(3)开发视角:数据库设计、算法设计、架构、内存占用、资源争用等。
三、性能测试的策略(性能测试类型)
1、基准测试:模拟一个用户访问使用被测系统的功能,属于性能测试的准备工作。
2、负载测试:模拟实际系统可承受的负载条件,通过逐渐加压的方式观测不同负载情况下系统各项性能指标,找到性能瓶颈。
3、压力测试(简称为”压测“):在强负载(用户多、业务数据量大、高并发)情况下,模拟峰值压力使用软件,进行性能测试,发现隐藏的性能问题,同时还需要长时间运行,关注软件的稳定性。 —最重要!!!
(1)稳定性压力测试:时间更长(一般是24小时或48小时)
(2)破坏性压力测试:使用极限负载(压力更大)进行测试。
4、容量测试:核实同时使用软件的最大数量(最大用户量、订单量、存储量、文件数量……),前提是配置不变。
5、并发测试:模拟多个用户同时访问软件的某一个功能(指同一个应用程序、或同一个模块、或同一条数据),发现资源争用的问题。
6、配置测试:为了进行设备选择,在保证操作不变的情况下,更换设备或更改配置,进行多轮性能测试,查看设备或配置对性能测试结果的影响,从而找到最优配置。
7、失败测试:为了测试容灾备份或负载均衡时,故意制造失败,进行备份服务器或其他服务器的性能测试。
四、性能测试的基本流程
1、性能需求分析—重要!!!
(1)查看产品经理(或需求分析师)所编写的《需求规格说明书》里所提出的性能要求(一般由他分析行业或与客户沟通得出的需求结论)


(2)如果没有性能要求,需要与相关人员沟通:产品经理、客户、项目经理、其他领导等,根据我们了解的行业业务经验以及早期运营数据来分析性能需求。
日活—初步分析稳定性、负载要求
峰值—判断和评估压力指标提供参考
(3)分析业务场景:单一场景、综合场景
(4)了解本次性能测试的意图、确定性能测试的目标
(5)最好明确各项性能指标:在线用户数、并发用户数、响应时间、错误率、资源占用率、单位时间内完成的工作量(吞吐量)等。
2、制定测试计划
(1)测试背景
(2)测试目的
(3)软件/硬件需要什么
(4)测试数据来源:有可能从真实的生产环境的数据库里下载下来,进行脱敏处理后,导入到我们的测试环境下的数据库里。
(5)人员分工和进度的安排
(6)测试场景和测试范围
(7)测试策略
(8)风险控制和停止结束的条件
(9)交付清单
3、测试环境搭建
(1)测试被测系统:比如ECShop
(2)测试工具和数据数据准备好
4、性能测试工具选型—可选!
(1)LoadRunner:LR,是HP公司的商业软件,需要付费,功能特别强大,重量级工具。
(2)JMeter:开源免费,可以做接口测试、性能测试。轻量级,小巧,扩展性好,支持分布式测试。
(3)Locust:Locust 是一个开源负载测试工具。使用 Python 代码定义用户行为,也可以仿真百万个用户。Locust 是非常简单易用,分布式,用户负载测试工具。
(4)Apache Bench(AB):是命令行工具,可以实现单一接口场景的性能测试。
……
5、测试用例设计(也叫做:测试方案、测试场景):
根据测试范围规定的内容,逐条设计测试需求以及完成需求的测试过程、测试条件,来构造本测试的测试用例。
(1)对于单个业务功能(场景)的性能测试,每个测试点都需要编写一个测试用例。
(2)对于多个业务功能(场景)组合测试,按照用户实际使用的业务场景,挑选出有代表性的业务流程编写测试用例。
6、测试脚本开发
(1)录制或编写一份基准测试的脚本
(2)根据测试用例里的用户数量(在线用户数、并发用户数)、增加压力的方式(逐渐增加、爆发式增加)、运行时间等要求,进行配置。
(3)测试数据的参数化、断言(数据检查)、思考时间(让测试脚本更真实模拟客户的使用)等方式来增强脚本。
(4)增加结果收集模块。
7、执行测试:
(1)如果模拟的压力不大,可以用图形化界面方式运行。
(2)如果模拟的压力较大,可以用命令行方式运行(减少电脑资源占用)。
(3)如果模拟的压力特别大,也可以使用分布式测试。
8、结果分析
9、调整配置—可选!只有配置测试才用到
10、测试结果总结
五、JMeter安装
1、JMeter=Java Meter,它是用Java语言开发的一个桌面应用。可以用来做接口测试、性能测试。
2、特点:开源免费、支持二次开发(可扩展)、支持分布式测试和远程执行、跨平台。
3、JMeter官网:http://jmeter.apache.org/
4、安装包:老师下发的资料包里的apache-jmeter-5.4.1.zip(它是一个在Windows系统上使用的安装包)
补充:Linux上使用的安装包是.tgz格式。
5、JMeter实现原理:采用Java多线程技术来进行多个虚拟用户的模拟。
6、安装配置jdk1.8
(1)jdk1.8安装包:老师下发的资料包里的jdk-8u281-windows-x64.exe
(2)检查当前电脑是否已经安装过jdk1.8:如果已经安装过,不用卸载重新安装,如果没有安装过,就用安装包进行安装。
(3)安装:一直使用默认配置进行安装即可。
(4)安装路径(jdk根目录):C:\Program Files\Java\jdk1.8.0_152
(5)打开环境变量配置窗口:查看是否存在名称是JAVA_HOME的变量,如果没有,就新建,如果有,就编辑它
变量名 JAVA_HOME
变量值 C:\Program Files\Java\jdk1.8.0_152
7、安装jmeter:解压缩,配置环境变量Path里,追加jmeter文件夹里的bin目录。
8、启动jmeter:cmd里输入jmeter回车启动它。
补充:打开jmeter文件夹里的bin目录,双击其中的jmeter.bat也可以启动它。
9、修改jmeter外观:
(1)黑色背景–>白色背景


(2)界面语言:英文–>中文
用记事本打开jmeter文件夹的bin文件夹里的jmeter.properties
搜索language=en,在它下面增加language=zh_CN,保存,关闭该文件,重启jmeter。
六、书写基准测试的脚本代码
1、JMeter里的测试计划(Test Plan):是一个管理单元,负责管理一次测试的所有步骤和报表信息,被保存在一个.jmx后缀的文件里。
2、在JMeter中一个测试计划至少要包含三个部分:
(1)一个**线程组**(Thread Group):管理多个Java线程,每一个线程模拟一个用户(称为一个“虚拟用户“)
(2)一个**取样器(Sampler):实现一个具体的业务操作(一个步骤,一般技术上来说本质就是一个请求),取样器是线程组的下一级。**
(3)一个**监听器**(Listener):负责收集和统计测试结果。
说明:监听器如果放在测试计划下,就可以看到整个测试计划里的所有程序的运行结果,如果放在一个线程组下,只收集这一个线程组执行的结果。
3、增加一个线程组


4、线程组下—添加—取样器—HTTP请求

5、测试计划下—添加—监听器—察看结果树

6、HTTP请求
(1)协议:一般是http或https
(2)服务器名称或IP:被测系统服务器的域名或IP地址
(3)端口号:Web服务所占用的端口(例如Apache默认占用的是80端口)
(4)请求方法:常用的GET或POST
(5)路径:访问的服务器资源的地址
(6)内容编码:最常用的编码是utf-8(说明:ECShop使用的编码是gbk)
案例:打开ECShop前台首页
名称:HTTP请求-打开前台首页
协议:http
服务器名称或IP:localhost
端口号:80
请求方法选择的下拉列表:默认选项是GET
路径:/upload/index.php
内容编码:gbk
7、保存测试计划:保存后才能运行。



8、运行当前脚本:

9、察看结果树:左侧点击“察看结果树”,右侧看到绿色对号说明,运行能成功(请求能发送,并也能接收到200响应码的响应)


补充说明(接口文档里面不全的话可以抓包)
1、Fiddler抓包时,如果用Firefox(火狐)不支持localhost的抓取。如果用Chrome可以支持。
2、Chrome访问ecshop前台留言板页(http://localhost/upload/message.php)
3、启动Fiddler,抓这个包



4、配置HTTP请求

说明:参数可以查看Inspectors下WebForms表格,如果为空,就是无参。
5、保存、运行
七、HTTP请求里的四种传参方式
1、方式一:路径传参
(1)应用场景:key-value格式的参数,参数较少,并且参数值较短,没有中文和特殊符号
(2)格式:
路径?key1=value1&key2=value2&key3=value3……
案例:HTTP请求-打开注册页
协议:http
服务器:localhost
端口号:80
请求方法:GET
路径:/upload/user.php?act=register
内容编码:gbk



2、方式二:参数表传参
(1)应用场景:键值对(key-value)格式的参数较多,或参数值较复杂。
(2)把参数名和参数值的信息都填写在下方的“参数”的表格里。
说明:可以点击“添加”按钮后,逐个书写参数名和参数值,也可以从Fiddler的Inspectors下WebForms表格中Ctrl+a全选后Ctrl+c复制,到JMeter中参数表下点击“从剪贴板添加”按钮来一次性粘贴所有键值对。
注意:路径里只写问号之前的内容。



(3)说明:Get请求的参数或Post请求的参数,只要是键值对格式的,都可以通过参数表来传参。
Post请求的参数,只要是键值对格式,那么它的内容类型
Content-Type: 是application/x-www-form-urlencoded



(4)关于编码的说明:如果参数数据里有中文,需要勾选“编码”复选框。

3、方式三:消息体数据传参
(1)应用场景:POST请求的参数的格式是json(HTTP请求头里Content-Type是application/json)
(2)JMeter—HTTP请求—切换到下方的“消息体数据”—输入JSON就可以。
4、方式四:文件上传传参
(1)应用场景:POST请求的参数的格式是文件格式(HTTP请求头里Content-Type是multipart/form-data),主要用于文件上传的时候使用。
(2)准备要上传的文件:


(3)抓包:POST请求头里Content-Type

(4)JMeter----HTTP请求—选择POST类型—勾选“对POST使用multipart/form-data”复选框!!!

(5)把不是的哪些键值对,一个一个添加到JMeter的“参数”表里。

从Fiddler的WebForm中复制一个单元格的内容,粘贴到记事本,在记事本里只复制其中的name=的名称。
在Jmeter参数表里“添加”,双击名称,粘贴那个字符串。

(6)**是**的项目,需要添加到JMeter—HTTP请求—“文件上传”表里。


文件的路径:不写文件的路径,只写文件名称,那么默认到当前.jmx脚本文件所在的文件夹里进行查找。

问题:FileNotFoundException文件未找到

解决方案一:把这个文件复制到.jmx脚本所在文件夹里。


或描述子文件夹的路径


\files\12345.txt

解决方案二:“文件上传”表格里第一个列
“文件名称”里填写文件所在的路径。


补充Fiddler抓包中文乱码
1、案例:

2、Fiddler抓包出现乱码

3、解决方案:
(1)分析当前被测系统使用的编码

(2)修改Fiddler注册表里的默认编码:按下Win+r组合键,在“运行”对话框里输入regedit回车,就可以打开“注册表编辑器”

计算机—HKEY_CURRENT_USER—SOFTWARE或Software—Microsoft—Fiddler2(点击到此项目上,不用展开它)。


在右侧空白区域里右击—新建—字符串值,输入名称HeaderEncoding


双击这行记录,输入目标被测系统的编码格式(比如:gbk),点击“确定”,关闭该窗口。

(3)重启Fiddler,重新抓包

八、配置元件-HTTP请求默认值
1、问题:复用性差,反复在多个HTTP请求里配置了相同的协议、服务器、端口、编码等信息。

2、配置元件:JMeter里专门做一些系统配置使用的组件。
3、HTTP请求默认值:属于“配置元件”中一个。可以配置当前作用域内的HTTP请求的配置信息的默认数据。提升复用性。
4、测试计划—添加—配置元件—HTTP请求默认值

5、在HTTP请求默认值里配置各项信息,这样在每一个HTTP请求里就不需要配置。


九、配置元件-HTTP Cookie管理器
1、案例:有效的登陆账号用户名是vip,密码也是vip,登陆后,进入用户中心
2、问题:由于JMeter默认没有管理前一个请求返回的Cookie信息,导致后一个请求是无Cookie的方式发送,造成因为HTTP协议的无状态性,没有记录登陆状态。



3、解决方案:测试计划—添加—配置元件—HTTP Cookie管理器




十、测试计划里的配置
1、用户定义的变量:
(1)应用场景:当某些配置数据或参数数据,需要复用时,为了方便后期数据修改,可以提前保存在变量里。
(2)如何添加?点击“添加”—输入自定义的变量名称—输入变量的值(注意:不用加引号,也最好不要加空格)

(3)如何使用?在整个测试计划里,需要使用变量的位置,使用${变量名称}的语法,就可以引用到该值。


2、测试计划里没有修改复选框配置时:默认执行的顺序是
(1)多个线程组同时运行
(2)线程组里的多个取样器顺序运行
3、测试计划里勾选“独立运行每个线程组”复选框:线程组也像HTTP请求那样顺序执行。

4、线程组分为三类:
(1)线程组:普通的线程组,负责实施具体的压力工作。
(2)setUp线程组:给普通的线程组做准备工作(数据准备或业务功能操作的准备),在所有普通线程组之**前**运行。—了解!

(3)tearDown线程组:给普通的线程组做收尾工作,在所有普通线程组之**后**才运行。—了解!


说明:不论setUp线程组、tearDown线程组、(普通)线程组在测试计划下的书写顺序如何,都是按照线程组的类型决定运行顺序的。
5、测试计划:其他配置一般不常用。
十一、线程组里的配置—重点!!!做性能测试时重点需要配置的位置。
1、线程数:要模拟的虚拟用户的数量(每个JAVA线程模拟一个虚拟用户)
2、案例:模拟**10**个人打开前台登陆页
前台登陆页:http://localhost/upload/user.php



3、Rump-Up时间(秒):在多少秒内启动所有的线程,用来设置启动线程的频率。采用匀速的方式启动线程。
(1)例如:线程数量是10,Rump-Up时间是10,就是在10秒内匀速启动10个线程,平均每一秒启动一个。

(2)建议:增加一个新的监听器—用表格察看结果


(3)说明:Rump-Up时间越小,模拟出来的瞬时压力越大,默认值1代表1秒内启动所有线程。****根据业务发生的实际频率来设置合理的秒数。
(4)举例:打卡系统,每天早上8点半到9点之间,有1000个人打卡,那么线程数设置为1000,Rump-Up时间设置为半小时对应的秒数(30x60=1800)。
4、循环次数:模拟每个虚拟用户反复执行多次该线程组下的取样器操作。例如一个用户反复查询商品。
5、稳定性测试的配置:需要对性能测试的时间有要求
(1)循环次数:勾选“永远”复选框
(2)勾选“调度器”
(3)设置“持续时间(秒)”

说明:如果循环次数没有设置为“永远”,并加入调度器里的持续时间,那么循环次数结束或持续时间到,都会停止。
6、**Same user on each iteration:**是JMeter5.2版本上增加的功能,代表每次循环都使用相同的用户(共享、复用Cookie信息)。—了解!

7、延迟创建线程直到需要:—了解!
(1)默认不勾选代表在运行开始时,就把所有线程全都创建出来,然后按照Ramp-Up时间约定的频率,进行请求的发送。
(2)如果勾选该复选框,代表按照Ramp-Up时间约定的频率,时间到的时候才创建线程,立即进行请求的发送。
(3)当电脑资源有限,而且要模拟较大的压力时勾选它。
8、启动延迟(秒):点击运行按钮后,延迟多久再开始运行本线程组。

何时需要增加启动延迟?
(1)用来约定多久后开始运行。
(2)用来在多线程组时,模拟一波一波的压力叠加的情况,第一个线程组不加延迟、第二个线程组加一些延迟、第三个线程组加更多的延迟……
注意事项:启动延迟需要与持续时间一起使用。
十二、测试HTTPS请求
1、HTTPS=HTTP+SSL,是比HTTP安全性更高的通讯协议。
2、SSL是安全套接字协议(安全套接层)
3、HTTPS单向认证和双向认证:
(1)**单向认证:**只对服务器做认证。
(2)**双向认证:**服务器和客户端都需要认证。
4、JMeter中单向认证可以直接测试,如果是双向认证,需要准备证书配置到JMeter的SSL管理器里。JMeter中支持的证书格式是keystore格式(.store后缀的证书文件)。
5、案例:百度首页上用关键词abab搜索
6、第一步:Chrome访问百度首页,利用Chrome导出证书
(1)以管理员身份启动Chrome浏览器

(2)访问https😕/www.baidu.com
(3)点击地址栏前面的锁头图标

(4)点击”证书“相关的超级链接,比如证书信息、证书、证书有效……

(5)详细信息,复制到文件(导出到文件、导出证书)

(6)下一步

(7)下一步

(8)E:\baidu1.cer

(9)完成,导出成功

(10)到E盘查看

7、第二步:转换生成.store格式的证书文件
(1)确认前面已经安装过jdk1.8
(2)输入命令确认环境变量是否已经配置过

(3)利用jdk里自带的keytool工具输入命令来转换证书格式:
cmd里输入命令
keytool -import -alias “baidu1.store” -file “E:</font>baidu1.cer” -keystore “E:</font>baidu1.store”
输入密钥库口令: —输入123456,按下回车
再次输入新口令: —输入123456,按下回车
……
是否信任此证书? [否]: y
证书已添加到密钥库中 —代表成功!!!
(4)到E盘查看

8、第三步:启动JMeter,新建一个脚本,把.store格式的证书导入进去


9、第四步:制作脚本
测试计划
线程组
HTTP请求-打开百度页
HTTP请求-用关键词abab搜索
察看结果树
HTTP请求默认值
HTTP Cookie管理器
HTTP信息头管理器

协议:https
服务器:www.baidu.com
端口:443
内容编码:utf-8




10、首次运行时,需要输入证书密码:在第二步中设置的口令(就是123456)

11、注意事项:针对访问限制要求严格的网站,建议增加请求头的配置
(1)默认JMeter的请求头,可能被某些服务器限制访问。

(2)改进方案:测试计划—添加–-配置元件—HTTP信息头管理器。

从Fiddler抓到的包里复制Client部分的每一项信息头


一项一项添加

12、运行调试,查看到请求—Request Headers(请求头)信息出现在Jmeter结果里。


十三、断言(Assertion)
1、为什么要加断言?
发送了请求,需要对响应数据是否正确做检查,这样才是真正的测试。
2、断言何时执行?
响应数据返回以后才执行。也就是说,是在取样器之后执行。
3、断言作用范围:
(1)断言在取样器下级:那么只对该取样器有效。
(2)断言在线程组下级:那么只对该**线程组里的所有取样器**有效。
(3)断言在测试计划下级:那么对该**测试计划下的所有线程组里的所有取样器**有效。
4、JMeter里常用的断言:

(1)响应断言:最简单、最方便使用!—做基础检查。
(2)JSON断言:响应数据格式如果是JSON时使用的专项断言。
(3)BeanShell断言:功能最强大,语法最复杂,难度大,最灵活。
5、响应断言—重点!!!!
(1)应用场景:对响应状态码和响应体数据做基础检查。
(2)案例:打开ecshop前台首页和使用关键词a进行搜索
(3)**针对第一个请求:**打开前台首页
断言一:断言响应状态吗是200
断言二:断言响应体文本里包含“欢迎光临本店”




(4)**针对请求二:**用关键字a搜索
断言一:断言主取样器响应状态码等于200

断言二:断言主取样器的响应体文本里包含“P806”和“本店价”和“购买”



断言三:断言子取样器的状态码是302或200

断言四:断言子取样器的URL里包含”category“或”encode“

(5)模式匹配规则:
包括:实际值包含一个预期**正则表达式**所匹配的字符串
匹配:实际值**等于一个预期正则表达式**所匹配的字符串
相等:实际值**等于**预期值(字符串)
字符串:实际值**包含**预期值(字符串)
**说明:**正则表达式是用来描述字符串所符合的规则的一种表达式技术,其中有各种符号来描述各种规则。
案例:
响应断言-响应状态码是以2开头的三位数字
2\d\d —正则表达式 \d代表一个数字字符

响应断言-断言响应体文本里包含“欢迎……本店”
欢迎.本店 —正则表达式 . 代表不包含换行符的任意字符串
6、补充:响应状态码是3xx,代表重定向(所请求的资源子在另一个URL地址处)
(1)主取样器(Main-Sample): 多次重定向最后的请求和响应数据记录在此处。
(2)子取样器(Sub-sample):每次发送请求和响应的数据记录在每一个子取样器。
(3)说明:取样器-HTTP请求
自动重定向:****在测试结果里只显示主取样器的内容,不显示子取样器内容。
跟随重定向(默认):在测试结果里显示主取样器和所有子取样器内容。


(4)响应断言里:Apply To(作用范围)
Main sample and sub-samples:**主取样器和所有子取样器**都做此断言
Main sample only:只对**主取样器做此断言** —最常用!
Sub-samples only:只对**所有子取样器**做此断言

7、断言的专用监听器-断言结果
测试计划—添加–监听器–断言结果
好处:可以方便查看到所有取样器执行断言之后的结果,汇总下来展示,如果有断言失败,直接就展示出来,不用做太多的操作。


8、JSON断言
(1)应用场景:只有**响应体是JSON格式的时候使用。**
(2)功能:可以从JSON里精确提取信息,对该信息进行检查。
(3)**案例:**ecshop前台打开P806商品详情页、将它加入购物车

(4)业务:HTTP请求-把P806加入购物车,响应体数据格式是JSON,key是error如果值是0代表没有错误。
(5)JSON Path:JSON路径表达式,可以用于在JSON里通过描述节点所在的路径来提取或查找特定的信息。
(6)JSON Path基础语法:
$ JSON根节点(代表整个JSON)
$.key 得到某个key对应的值(value)—点表示法,语法简洁,但是key里不允许包含空格。
$[‘key’] 得到某个key对应的值(value)—中括号表示法,更通用(可以适应各种key的用法),语法更复杂。
(7)JSON Path校验:利用JMeter察看结果树


(8)增加JSON断言



(9)**JSON Path高级语法:**应用于较为复杂的JSON中使用。
$.key[下标] —key的值是数组时,用下标(从0开始编号)获得数组里的其中一个值。


$.key1.key2 —key1的值是JSON对象时,用连续用点查找下一级JSON中的某个key的值


$…key —在各个级别的JSON里查找某个key的值。


9、BeanShell断言:语法最复杂,功能最强大。—了解!
(1)BeanShell是什么?
BeanShell是以Java为基础,嵌入在JMeter中使用的一种小型脚本语言,只要有jdk和jmeter就可以被执行。
(2)BeanShell语法=Java语法+为JMeter设计的语法
(3)BeanShell官网:http://www.beanshell.org/
(4)取样器—添加—断言—BeanShell断言

(5)日志查看

(6)手写脚本:
获得响应状态码:
String 变量名=prev.getResponseCode();

(7)分支结构来进行断言,断言结果记录在变量Failure里,失败消息记录在变量FailureMessage里。
说明:Failure的值是true代表失败,false代表成功。
//获得响应状态码
String c=prev.getResponseCode();
log.info("===========");
log.info(c);
//判断该响应状态码是否等于“200”
//如果等于
if(c.equals("200")){
//向监听器里记录断言成功的结果
Failure=false;
}else{
//向监听器里记录断言失败的结果
Failure=true;
//定义失败消息(描述失败的原因)
FailureMessage="状态码不是200,而是"+c;
}
(8)另外:
获得响应体的文本字符串:
String 变量名=prev.getResponseDataAsString();
判断字符串包含xxx:
变量名.contains(“xxx”)
条件表达式可以使用逻辑运算符(if里面)
&& (与) 、 || (或)、 ! (非)
//log.info("===============Hello World=================");
//获得响应状态码
String c=prev.getResponseCode();
log.info("===========");
log.info(c);
//获得响应体数据
String d=prev.getResponseDataAsString();
//判断该响应状态码是否等于“200”并且响应体数据里包含“欢迎”
//如果条件满足
if(c.equals("200") && d.contains("欢迎")){
//向监听器里记录断言成功的结果
Failure=false;
}else{
//向监听器里记录断言失败的结果
Failure=true;
//定义失败消息(描述失败的原因)
FailureMessage="状态码不是200,而是"+c+"或者响应体数据里不包含“欢迎”";
}
十四、JMeter关联
1、什么是关联?
<font style="background-color:#FADB14;"> 前一个取样器的响应数据里,有一些内容,是后一个请求发送时要携带的数据或后面的断言检查时要使用的预期值数据</font>,**<font style="color:#E8323C;">那么需要使用关联技术把数据从前面的响应中</font>****<font style="color:#52C41A;">提取</font>****<font style="color:#E8323C;">出来,存储在变量里,给后面取样器或断言使用。</font>**
2、关联的步骤:
(1)提取数据:JMeter提供的“后置处理器”中的各种“提取器”—重点!!!
(2)**使用数据****:**容易 ${变量名}
3、应用场景:
业务数据(比如订单号、商品号、总数、商品价格……)、权限数据(比如Token)
4、案例:
HTTP请求-打开P806商品详情页
<u>xxx提取器-提取该商品当前价格值</u>
HTTP请求-加入购物车
<u> xxx断言-检查商品当前价格值出现在响应体里</u>
5、后置处理器:
** 在取样器执行之后,要进行处理时使用的组件。**
6、JMeter常用的后置处理器:
(1)边界提取器:通过左右边界提取,最简单、最好理解。
(2)正则表达式提取器:利用正则表达式描述目标字符串附近的规则
(3)BeanShell后置处理器:**利用BeanShell脚本处理提取。**难度大。
7、边界提取器:
(1)前一个取样器—添加—后置处理器–边界提取器

(2)分析:前一个取样器的响应体里,目标字符串的左右边界是什么。
本店售价:<font class=“shop” id=“ECS_SHOPPRICE”>¥2000元
2000 —要提取的目标字符串
id=“ECS_SHOPPRICE”>¥ —左边界—长度不限(自己衡量)
元
—右边界—长度不限(自己衡量)
(3)配置:
Apply To:一般默认选项(主取样器)
要检查的响应字段:一般都是默认选项(主体—代表Response Body)
引用名称:变量名称(自己随便定义,用来存储所提取的数据)
左边界:目标字符串左侧的一部分字符串
右边界:目标字符串右侧的一部分字符串
匹配数字:提取符合条件的第几个值(第一个就填写1、第二个就填写2……),0代表随机。
缺省值:如果提取失败,那么变量的值就是此处设置的值,可以为空。

(4)为了调试:可以增加调试取样器(Debug Sampler)

(5)查看变量的值:查看结果树—调试取样器—响应数据—Response Body里查看到所有JMeter变量的当前值。

(6)使用变量的值:${price}


8、正则表达式提取器
(1)分析:目标字符串符合什么规则,要提取的部分需要用小括号括起来,前后的字符串也可以使用正则表达式里的符号描述规则(也可以使用固定字符串)
本店售价:¥2000元
正则表达式: \d*代表n位数字(n可以是0到无数)
ECS_SHOPPRICE">¥(\d*)元
(2)前一个请求—添加—后置处理器—正则表达式提取器

(3)配置:
引用名称:变量名
正则表达式:提取规则(小括号里的内容是要提取的,可以有多个小括号用于一次提取多个数据)
模板: 1 1 1使用第一个小括号里提取出来的数据, 2 2 2使用第2个小括号里提取出来的数据…… 1 1 1 2 2 2代表第一个和第二个小括号里的数据。
匹配数字:提取符合条件的第几个值(第一个就填写1、第二个就填写2……),0代表随机。
缺省值:如果提取失败,那么变量的值就是此处设置的值,可以为空。

(4)变量的用法与边界提取器基本相似。
9、BeanShell PostProcessor(BeanShell后置处理器、BeanShell 后置处理程序):可以用于提取数据,也可以用于做其他的后置处理。—了解!!!!
(1)前一个取样器—添加—后置处理器—BeanShell PostProcessor

(2)编写脚本:获得响应体,从中查找目标左侧字符串,查找目标右侧字符串,提取这两个字符串中间的字符串

String a=prev.getResponseDataAsString();//获得响应体
int i=a.indexOf("E\">¥");//查找到左边界的字符位置 \转义
int j=a.indexOf("元</font><br />",i);//查找右边界的字符位置,i参数代表从i索引之后找
String b=a.substring(i+4,j);//截取目标字符串 i是E的索引 从">¥后面截取
log.info("================");
log.info(b);//输出目标字符串到日志里
vars.put("price",b);//存储目标字符串数据到JMeter变量price中
(3)编写脚本:把提取的内容存储在JMeter变量里,这样才能在后续的图形化界面的组件里使用(取样器、断言)。
例如:
vars.put(“price”,b);//存储目标字符串数据到JMeter变量price中
十五、JMeter参数化
1、为什么要做参数化?
模拟不同的客户使用不同的数据进行操作,就**需要把参数或路径里的一些数据替换为”参数“。**
2、JMeter中参数化实现方式:
(1)方式一:利用函数助手生成动态数据作为”参数“。
(2)方式二:****前置处理器-用户参数。—适用于参数较少的情况,初学者使用较为方便。—接口测试中常用!
(3)方式三:配置元件-CSV Data Set Config(CSV 数据文件设置),可以读取外部csv格式的数据文件里的数据作为”参数“。—适用于**数据较多的情况**。—性能测试中常用!
3、利用函数助手生成动态数据:
案例:打开首页,打开随机编号的商品详情页
随机范围:19-27号之间
(1)打开函数助手

(2)举例:为了生成一个**随机整数**,可以在下拉列表里找到名称是Random的函数

(3)输入参数,点击“生成”按钮
前两个参数是必填项(最小值、最大值)

说明:点击“生成”按钮,就会自动复制这个函数的调用语句。${__Random(19,27,)}
(4)在测试脚本中,删除原来的固定整数数据,粘贴函数调用语句。

(5)思考:如何对使用了随机数的取样器做结果的断言?
断言的预期值随着随机数参数变化而变化。
例如:打开的商品编号是多少,那么响应数据里的商品货号就是“ECS0000+随机数”
**方案:**增加随机数函数Random的第三个参数,就是存储结果的变量名(可选,变量名自己随便定义)

在第一次使用该随机数的位置上,粘贴函数调用字符串,第二次以后再需要使用该数据时,需要使用${变量名}的语法来使用它。

**说明:**常量和变量连接直接书写在一起就行,不需要任何连接符号。

(6)假设:用BeanShell断言实现数据检查,那么BeanShell脚本获得某个Jmeter变量的值,需要使用的语法
String BeanShell脚本里可以使用的变量=vars.get(“JMeter变量的名称”)

String a=prev.getResponseDataAsString();
String b=vars.get("num");
String c="ECS0000"+b;
if(a.contains(c)){
Failure=false;
}else{
Failure=true;
FailureMessage="响应体里不包含预期商品货号"+c;
}
4、利用函数助手生成唯一的数据(不与以前生成的数据重复)
(1)应用场景:****有些测试数据要求与前面的数据不能重复。
(2)**案例:**多人注册会员账号时,用户名和邮箱是不允许重复的。
(3)方案一:UUID函数专门用于构建唯一值,缺点是长度较长
2067a736-1c53-4983-a5ac-60adf62fea5a

(4)方案二:time函数生成系统日期时间的数据,因为时间不会倒流,所以该数据也有唯一性。
不加参数:13位时间戳
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
1664349771245
加参数:
第一个参数(可选):日期时间的格式,Y代表年、M代表月、d代表日、H代表小时、m代表分、s代表秒、S代表毫秒。几个字符代表几位。这个字符之间还可以增加自定义分隔符。
第二个参数(可选):存储结果的变量名。

(5)使用time函数
参数表里的”用户名“的值:粘贴
参数表里的”邮箱“的值:[ t @ 126. c o m ] ( m a i l t o : {t}@126.com](mailto: t@126.com](mailto:{t}@126.com)
响应断言的预期值:用户名${t} 注册成功 —注意空格!

5、前置处理器-用户参数
(1)使用场合:参数数据量较少,准备固定的一些数据。
(2)前置处理器:在取样器执行之前,做一些准备工作的组件。
(3)**案例:**模拟多个用户在留言板页面进行匿名留言,每个用户留言的信息是不一样的。
(4)取样器-添加-前置处理器-用户参数


(5)添加变量:按照要做成参数的数据个数来”添加变量“,每次都会在表格里生成一个新的数据行,在第一个列里自己定义变量名称来代表这些参数。

(6)要根据测试数据组数(或模拟的用户的数量)来”添加用户“,并输入各个用户的测试数据(每个用户一个列)。

(7)使用这些参数(也就是变量):在取样器或断言里使用${变量名称}的语法格式就可以引用它。

6、配置元件-CSV Data Set Config(CSV 数据文件设置)
(1)csv:**逗号分隔值。**准备数据文件时,可以先新建一个文本文档,用记事本打开,书写测试数据内容。
示例:
电子邮件地址,留言类型,留言主题,留言内容
zhangsan@126.com,0,hello,hi
lisi@163.com,4,你好,789
wangwu@gmail.com,2,我是王五,456
注意事项:第一行是注释,每行里的逗号个数必须一样,而且必须使用英文逗号。
(2)保存文件:用”另存为“保存,选择文件类型是”所有文件(.)“,输入文件名称xxxx.csv ,选择编码为”UTF-8“,保存。



(3)取样器-添加-配置元件-CSV Data Set Config(CSV 数据文件设置)

文件名:浏览—选择目标csv数据文件

文件编码:一般使用UTF-8
**变量名称:**用英文逗号分隔开多个自定义的变量名称(注意变量的个数必须与csv文件里每行数据值的个数一致,例如:e,t1,t2,c)
忽略首行:True代表csv文件里的第一行是注释,不需要使用它来做测试。
说明:其他配置项不用修改。

(4)使用**${变量名称}**来引用这些值。
(5)修改线程数,运行

(6)补充:文件名也支持相对路径

十六、并发测试(定时器-同步定时器)
1、**说明:**并发测试是性能测试中非常重要的策略。
2、取样器-添加-定时器-Synchronizing Timer(同步定时器)

3、配置:
(1)模拟用户组的数量:并发用户数量(简称为“并发数”),也就是“同时”执行某操作的人数。
注意:线程组里的线程数要大于或等于此处配置的并发数。
(2)超时时间:以毫秒为单位,代表到达此时间时,仍然没有集合到并发数量的线程,就会停止等待,继续执行。

4、增加监听器-用表格察看结果


十七、事务控制器
1、事务(Translation):模拟客户认为的一系列取样器的总体执行情况,加入事务来管理多个取样器,对结果信息汇总展示,总之,事务就是多个取样器的集合。
2、案例:
http://localhost/upload/admin/index.php --后台页(包含多个页面组成后台页-发送多个请求)
有效账号登陆:admin/admin123/0
客户登陆进入后台,会同时产生多个对服务器发送的请求。

3、线程组-添加-逻辑控制器-事务控制器

4、在事务控制器下添加多个取样器

5、察看结果树

十八、聚合报告
1、为了统计性能测试中多个线程执行后的性能测试结果,可以添加-监听器-聚合报告(Aggregate Report)
2、聚合报告的作用:用表格的形式汇总展示所有线程执行后,各个取样器和各个事务控制器执行的总体性能结果。
3、测试计划-添加-监听器-聚合报告

4、修改线程数

5、运行查看聚合报告里的结果
(1)Label(标签):默认显示的是取样器名称或事务控制器名称(说明:只要名称相同,就会汇总为一行信息)
(2)样本:采样的数量(该名称的取样器或事务控制器总的执行次数),由线程组里的线程数和循环次数、以及运行次数决定。
(3)平均值:毫秒单位,所有样本的平均响应时间-–非常重要!!!
(4)中位数(50%百分位)、90%百分位、95%百分位、99%百分位:有百分之多少的样本的响应时间在该值以下,单位也是毫秒。
(5)最小值、最小值:最大/小响应时间,单位也是毫秒。
(6)异常%:有百分之多少的样本出现异常,也可叫做“错误率”或“异常率”。
(7)吞吐量(Throughout):单位时间内服务器能处理多少请求或事务。时间单位可能是**秒**、分钟、小时。
(8)接收(KB/sec):平均每秒从服务器接收的千字节数据量,下行网速影响到此值。
(9)发送(KB/sec):平均每秒向服务器发送的千字节数据量,上行网速影响到此值。
十九、如何做性能测试?
1、**被测系统:**网站稿件管理发布系统。
2、**测试策略:**基准测试、负载测试、并发测试……
3、针对登录功能做基准测试和负载测试:
(1)**基础准备:**被测系统系统内置了50个有效账号,用户名分别是test01、test02……test49、test50,密码都是1111。
(2)设计测试用例:
编号:登录001
名称(标题):测试登录功能单用户在5秒内完成
步骤:打开登录页、用有效账号test01\1111登录
预期性能数据:平均响应时间<5秒
(3)制作脚本:
<1>新建脚本,添加JMeter组件

<2>按照接口文档或抓包数据,填写配置信息




<3>为了做**负载测试**,做参数化,添加监听器



<4>修改线程数,运行脚本,得到平均响应时间的实际值数据


4、针对稿件管理模块里的查询稿件功能做**并发测试**:
(1)用例:
编号:search001
名称(标题):查询稿件时支持20个用户并发操作
步骤:打开登录页、有效账号登录、查询稿件
查询稿件的并发数:20、在线用户数:50
预期**性能指标:**平均响应时间小于5秒、错误率小于0.6%
(2)制作脚本:其它步骤与前一个案例相似,但是并发测试需要增加同步定时器,设置用户组的数量是20


二十、常见的性能指标
1、什么是性能指标?
用来衡量软件的性能情况是否符合实际场景下的预期要求的一些数据称为“性能指标”,他们最终记录在性能测试结果报告里。
2、性能指标的类型:
(1)业务指标:****平均响应时间(ART)、错误率(Error)、吞吐量(Throughout)、**并发用户数(或在线用户数)**等。
说明:吞吐量有一个重要的数据单位是TPS(Transaction Per Second每秒事务数)
(2)系统资源指标:CPU、内存、磁盘空间、网络带宽占用率。
3、指标数据的行业标准:
(1)平均响应时间:指从发送请求开始,直到接收到响应所花费的总时间,如果是一个事务,从第一个请求发送,直到接收到最后一个响应所花费的总时间(不包括思考时间)
说明:需求没有明确说明的情况下,遵循2-5-8原则
2秒以内:非常好
2秒-5秒之间:不错
5秒-8秒之间:勉强接受
8秒以上:不能接受(需改进)
(2)用户数:分为三个,需要按照实际情况准备。
注册用户数:数据库里已经注册生成的数据量。
在线用户数:使用该软件的用户总量。—重要!
并发用户数:同一时间点同时使用某个功能的用户数量。—重要!
(3**)吞吐量:**用来衡量软件提供服务的能力(效率),单位时间内完成多少任务。
TPS:每秒事务数
RPS:每秒请求数
行业原则:二八定律,百分之八十的任务都集中在百分之二十的时间里完成。
案例:淘宝一天完成30万笔交易(日活30万)
TPS预期值估算: 3000000.8/(2460600.2)
(4)错误率(失败率):一般行业里要求在千分之六以下。
(5)系统各项资源占用率一般要求在75%以下(有的公司要求80%以下)
CPU占用率、内存占用率、磁盘空间占用率、网络带宽占用率等。
二十一、JMeter运行模式
1、JMeter两种运行模式:GUI模式、CLI模式(Non GUI模式)
(1)GUI模式:**图形化界面模式,用jmeter.bat启动的Jmeter界面用绿色三角号运行**。—用于脚本创建和调试使用,因为占用电脑资源多。
(2)**CLI模式:**命令行模式,不启动Jmeter界面,使用cmd里的命令来运行脚本。—用于性能测试使用,可以模拟更多的用户。
2、CLI模式运行:cmd窗口里输入命令,命令格式如下
jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
(1)[jmx file] — 目标脚本的路径
(2)[results file] — 支持.jtl(常用!)或.csv格式的测试结果文件,该文件可以在JMeter图形化界面的所有监听器里打开查看。

(3)[Path to web report folder] —存储html格式的测试结果报告文件的文件夹路径。html格式的测试结果报告文件可以在任何一款浏览器里打开查看。
3、CLI模式运行命令实例:
jmeter -n -t E:\scripts\s6003.jmx -l E:\res1.jtl -e -o E:\report1
注意事项:res1.jtl文件必须是不存在的,report1文件夹必须是不存在的。但是他们的所在路径要求是存在的。
4、运行结束,可以到指定的路径下查看结果文件和web版本html报告是否生成。


5、启动JMeter图形化界面,用一个监听器打开.jtl格式的测试结果


说明:如果打开过jtl文件,下次在图形化界面上运行时会有提示

第一项:追加样本。
第三项:覆盖它,只显示最新结果。
6、查看html报告(web版本)测试结果报告:可以打包分享给他们进行查看。

二十二、常见面试题
1、你的项目里用户数多少(每天活跃用户或在线用户有多少?)并发数多少?
根据项目的规模和使用的人员目标群体来描述。
如果**互联网给所有网络用户用,那么用户数可以说2000或3000. 并发数是200或100**
如果**内部企业使用的软件,那么用户数可以说300或500,并发数是80或50**
2、性能测试分为哪些类型?
基准测试、负载测试、压力测试、容量测试、并发测试、失败测试……
3、性能测试指标有哪些?
在线用户数、并发用户数、吞吐量、平均响应时间、错误率、各种资源占用率
4、性能测试用例怎么写?
目标(名称)、用户数、策略、步骤、预期性能指标范围
5、怎么分析性能瓶颈?
查看性能测试指标,看哪些值是超过范围、出现拐点的时间,查看当时的各项资源占用率,分析性能瓶颈可能在哪里,有可能CPU、内存、数据库、网络上行下行网速
6、JMeter函数集里有哪些?Random、UUID、time……
7、响应时间和吞吐量有什么关系?
一般情况下**响应时间越短,吞吐量越大,吞吐量除了与响应时间有关,还与用户数和并发数有关。**
12万+

被折叠的 条评论
为什么被折叠?



