接口测试必备
接口文档、协议、请求方式、请求地址、请求参数、返回值。
接口测试类型
功能、安全性、性能。
性能不好的表现
12306买票崩溃,微博热搜崩溃,双11崩溃等。
大量用户用大量的数据访问程序,程序表现未能达到预期。
有些系统会通过通过提升自己本身性能去提升用户体验,有些系统则会千方百计限制用户在某一时段的访问来满足性能要求
**性能的表现:**软件又好(功能)又快(性能),在软件功能正确情况下在考虑性能
从黑盒测试角度的性能表现
从系统维护角度的性能表现
从程序开发角度的性能表现
**定义:**通过自动化测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试
对于性能测试,测试过程不重要,重要的是对于性能测试前的分析,每种软件的性能变化都是不一样的。如购物软件,性能会随着一些特定日子产生大量波动;而像微博新闻这种,会随着出现重大新闻而波动
性能测试分类
我们用一个瓶子举例来表现性能测试分类
向瓶子内加水(数据、访问量等),若只是溢出则是局部崩溃。系统还能用,若是瓶子裂开,那就是全面崩溃,系统不能用。
数据到达峰值,系统还没崩溃,但是在多家一点系统就崩溃,该峰值称为系统瓶颈
虚拟用户:测试环境中,通过测试工具在物理计算机上使用vuser来虚拟实际用户
点击率:每秒用户向服务器提交的请求数量
并发和并发用户数:并发强调大量用户的同时操作(能对服务器产生压力的操作),注意在线用户数和系统用户数是两种用户
每秒事务数TPS:每秒系统能够处理的交易或者事务数量
根据不同系统要求不同,
响应时间:包含请求响应时间和事务响应时间
用户角度自己的带宽,运营商的服务器数据处理,电脑处理速度等都会影响响应时间
请求响应时间:服务器收到用户请求然后把响应内容发送出去这段时间
事务响应时间:服务端处理请求(后端调用函数处理业务)的时间
吞吐量:在单次业务中,客户端和服务端进行的数据交互总量
吞吐率:吞吐量/传输时间=吞吐率,衡量服务器性能和网络性能重要指标之一。可以用请求数/秒、页面数/秒、字节数/秒进行衡量
思考时间:两次请求之间的间隔时间(默认情况思考时间为0)
性能计数器:描绘各种类型服务器或者操作系统性能的指标,在进行资源监控和系统瓶颈分析起到重要作用
在功能测试通过后才会进行性能测试
性能需求分析-性能测试计划-测试环境搭建-测试工具选择-测试执行/测试结果分析/软硬件调整与优化
客户方提出需求,根据客户提供历史数据分析,在针对项目本身进行需求分析和定位,参考同业项目,参考其他资料数据。
**可以参考的比如:**响应速度、在线用户数、某个接口或功能的在某个时间并发数、请求的成功率、高峰期下系统表现、稳定性测试等
场景设计要从以下方面进行测试,系统运行时长、并发用户数量、系统执行操作时长、终止性能测试方式、在该场景中需要监控什么作为性能测试的指标、要采取什么方式来实现该性能、该场景是否符合实际使用需求、压力出现的指标(持续加压还是适当减压)
测试标准没有绝对,需要专家依据实际情况确定标准
对于性能测试人员,测试和优化性能的能力同样重要。我们需要提出解决性能问题的方案的能力
假设现在系统要求支撑200w用户在线
性能测试的指标是饭要一口一口吃,不能一口气吃成胖子,或者干脆不吃成瘦子
性能测试中的难点和重点
需求分析、场景设计、性能诊断和模拟、环境搭建和模拟
专业角度进行性能分析
注意因为性能测试是在功能测试后执行,所以不需要反向数据验证了,但是测试目的里包含很多测试要点
准确叫设计场景,性能测试用例设计本身时通过场景法设置用例,归根结底是设计场景
用事务代指用户操作行为的总称,用来衡量TPS(每秒事务数)、事务成率。
集合点表示所有用户集合在一起进行操作
常见性能工具:LoadRunner/Jmeter/Grinder/QALoad/WAS/WebLoad/RPT
loadrunner脚本语言是c
Loadrunner安装完后出现三个图标
LoadRunner自带一个体验订票BS系统Start HP Web Tours Server让用户体验LoadRunner
默认用户密码jojo/bean
Web Tours
刚使用LR12测试,浏览器使用是chrome,录制项目是LR自带的订票系统。
录制时无法打开测试网页
开始录制时碰见能打开浏览器,但是打不开网页的情况,后面网上排查发现打开fiddler就能重新录制,遇到Loadrunner的古怪问题一般打开fiddler都能解决,
fiddler都解决不了的话,别怕,我们还有终极大招:fiddler跟踪,保存成SAZ文件后,用LR12 open solution选项打开,然后就会发生令人感动到哭的一幕:LR12自动把fiddler跟踪文件转成了可以调试的脚本。这样的话,脚本问题解决了,就是得自己再去参照下添加事务
virtual user Generator引擎,可以监控并记录客户服务端通话,让虚拟用户模拟实际业务流程,记录用户操作行文,并将其转化为特定测试脚本语言
Controller创建测试场景,为了实现真是负载,让一台或多台机器模拟多个用户同时执行脚本。
每个场景都相当于一套负载测试方案,包括了反应业务操作流程的测试脚本,梵音系统承受能力的虚拟用户数量用于平衡测试机器自身压力
Analysis分析测试结果,导入前两个测试结果数据,帮助用户找到性能问题同时溯源,提供优化。
依次是单协议脚本、多协议脚本(需要考虑协议之间的冲突)、移动应用脚本、常用协议脚本和最近创建脚本所用协议
如果不知道测试系统支持什么协议,在创建脚本目录下有一个Protocol Advisor,可以检测被测应用支持的协议
- 一般根据被测应用采用BS结构还是CS架构来选择协议
脚本录制位置位置是有说道的
Vuser_init存放应用程序初始化脚本、Vuser_end存放和应用程序注销和关闭时的脚本、Action存放实际操作脚本,前两者都只执行一次
脚本重放前需要重新编译一下,编译通过后再进行重放,因为编译不通过重发是不能通过的
//是响应后的操作
web_link("测试结果中显示的名称","TEXT=需要单击的超链接名称",LAST)//模拟单击超链接操作,页面访问常用函数,LAST表示操作的时序性
web_link("clicklink","Text=https://www.baidu.com",ord=3,LAST)//多个重名超链接处理方案 ,多个重名超链接ord表示点击次序
//是请求的操作,模拟用户请求,访问型函数
web_url("header.html",
"URL=http://{host_127_0_0_1_1080}/WebTours/header.html",
"Resource=0",
"Referer=http://{host_127_0_0_1_1080}/WebTours/index.htm",
"Snapshot=t14.inf",
"Mode=HTML",
LAST) //url可以取代link
///操作表单。自动检测当前页面是否有form表单,有的话将内部数据进行post提交
web_submit_form("login.pl",
"Snapshot=t16.inf",
ITEMDATA,
"Name=username", "Value=jojo", ENDITEM,
"Name=password", "Value=bean", ENDITEM,
LAST)
//需要服务器返回一个页面,且起作用前必须含有form表单
//数据条目可以有多条, 第一个拿的是form标签的action属性值用作区分不同的form标签
//这样一条表示一个form表单提交数据数据"Name=username", "Value=jojo", ENDITEM
web_submit_data("login.pl",
"Action=http://127.0.0.1:1080/cgi-bin/login.pl","Method=POST",
"RecContentType=text/html" ,
"Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?in=home","Snapshot=t2.inf",
"Mode=HTML",ITEMDATA,
"Name=userSession",
"Value=123658.78217902zDzAzQipzAiDDDDDDiVztpVQVzf",ENDITEM,
"Name=username", "Value=jojo",ENDITEM,
"Name=password", "Value={PasswordParameter}", ENDITE"Name=login.x-", "Value=44",ENDITEM,
"Name=login.y" , "Value=14",ENDITEM,"Name=login", "Value=Login",ENDITEM,
"Name=JSFormSubmit , "Value=off",ENDITEM,
//与from不同不需要一定有页面响应才发送数据,而是直接给页面发送数据
lr_think_time()//思考时间,等待时间,单位s
lr_save_string(r_decrypt("5e54d38063296342"), "PasswordParameter");//记录一个字符串
lr_decrypt("5e54d38063296342")//加密字符串(结果)
web_image()//模拟鼠标点击属性定义的图像,一般设置后没有使用必要
事务是局部操作的汇总,TPS每秒事务数基础
事务
#对于事务,要有开始和结束,一下是一段脚本的截取
lr_start_transaction("login");
web_submit_form("login.pl",
"Snapshot=t21.inf",
ITEMDATA,
"Name=username", "Value=jojo", ENDITEM,
"Name=password", "Value=bean", ENDITEM,
LAST);
web_image("Search Flights Button",
"Alt=Search Flights Button",
"Snapshot=t22.inf",
LAST);
lr_end_transaction("login", LR_AUTO);
#事务开始和结束的宣称(事务的名称)必须保持一致,否则报错
加入事务后的体现
有了事务后最后统计结果时就能体现该登录事务下性能(通过或不通过),不通过是会展示原因,上图是事务验证通过后ouput的体现
事务可以相互嵌套,比如订票事务中可以穿插登录
注意录制脚本时允许手动添加事务
虚拟用户集合在一起实现并发操作,实现短暂时间的大量操作
什么是集合点
**对于集合点语句的设置,只能放在action脚本中,禁止放到初始化vuser_init()和vuser_end()中,且必须在事务开始之前,不能在事务中。**如下
lr_start_transaction(“login”);
#省略其他脚本代码
lr_rendezvous(“start”);
lr_end_transaction(“login”);
lr_rendezvous("start");
集合点设置步骤
虚拟用户有多少个需要放到场景中也就是Controller中设置,
设置集合点的释放策略,策略有四种,如下图
位置:Controller软件下Scenario->Rendezvous->policy
实际运行性能测试时,达到集合点的用户数量都看脸,所以集合点的运行结果几乎是不可能完美达成的。一般运行时间越长,可以达到集合点的用户梳理就越多
运行前后中,可以在Controller的run界面看到虚拟用户的运行状态。具体到每一个用户点击黑框位置就行,图下是显示
就是断言
什么是检查点
web_reg_find()
#要在网页请求之前进行检查点的注册
#检查点(断言)函数一般放在页面请求之前
使用检查点步骤
其他的断言函数需要后续学习了
实例运行(LR自带的订票系统)
需要检查登录页面是否正常,同时检查sign up now连接是否返回正确
Action()
{
//文本检查点
web_reg_find("Fail=NotFound",
"Search=Body",
"SaveCount=2",
"Text/DIG=Web Tours",
LAST);
web_url("index.htm",
"URL=http://{host_127_0_0_1_1080}/WebTours/index.htm",
"TargetFrame=",
"Resource=0",
"Referer=",
"Snapshot=t6.inf",
"Mode=HTML",
LAST);
// link检查点
web_link("web_link",
EXTRARES,
"URL=http://127.0.0.1:1080/cgi-bin/login.pl?username=&password=&getInfo=true", "Referer=sign up now", ENDITEM,
LAST);
web_url("header.html",
"URL=http://{host_127_0_0_1_1080}/WebTours/header.html",
"TargetFrame=",
"Resource=0",
"Referer=http://{host_127_0_0_1_1080}/WebTours/index.htm",
"Snapshot=t7.inf",
"Mode=HTML",
LAST);
web_url("welcome.pl",
"URL=http://{host_127_0_0_1_1080}/cgi-bin/welcome.pl?signOff=true",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=http://{host_127_0_0_1_1080}/WebTours/index.htm",
"Snapshot=t8.inf",
"Mode=HTML",
LAST);
//设置集合点
lr_rendezvous("start");
//定义订票事务开始
lr_start_transaction("order");
//定义登录事务开始
lr_start_transaction("login");
web_submit_data("login.pl",
"Action=http://{host_127_0_0_1_1080}/cgi-bin/login.pl",
"Method=POST",
"TargetFrame=body",
"RecContentType=text/html",
"Referer=http://{host_127_0_0_1_1080}/cgi-bin/nav.pl?in=home",
"Snapshot=t9.inf",
"Mode=HTML",
ITEMDATA,
"Name=userSession", "Value=133497.64690158zizzHifpcVcftVcAApHVVcHf", ENDITEM,
"Name=username", "Value=jojo", ENDITEM,
"Name=password", "Value=bean", ENDITEM,
"Name=login.x", "Value=55", ENDITEM,
"Name=login.y", "Value=4", ENDITEM,
"Name=JSFormSubmit", "Value=off", ENDITEM,
LAST);
//登录事务结束
lr_end_transaction("login",LR_AUTO);
web_url("Search Flights Button",
"URL=http://{host_127_0_0_1_1080}/cgi-bin/welcome.pl?page=search",
"TargetFrame=body",
"Resource=0",
"RecContentType=text/html",
"Referer=http://{host_127_0_0_1_1080}/cgi-bin/nav.pl?page=menu&in=home",
"Snapshot=t10.inf",
"Mode=HTML",
LAST);
web_reg_async_attributes("ID=Poll_0",
"Pattern=Poll",
"URL=http://{host_127_0_0_1_1080}/cgi-bin/reservations.pl",
"PollIntervalMs=1000",
"RequestCB=Poll_0_RequestCB",
"ResponseCB=Poll_0_ResponseCB",
LAST);
web_submit_data("reservations.pl",
"Action=http://{host_127_0_0_1_1080}/cgi-bin/reservations.pl",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://{host_127_0_0_1_1080}/cgi-bin/reservations.pl?page=welcome",
"Snapshot=t11.inf",
"Mode=HTML",
ITEMDATA,
"Name=advanceDiscount", "Value=0", ENDITEM,
"Name=depart", "Value=Denver", ENDITEM,
"Name=departDate", "Value=03/24/2022", ENDITEM,
"Name=arrive", "Value=Denver", ENDITEM,
"Name=returnDate", "Value=03/25/2022", ENDITEM,
"Name=numPassengers", "Value=1", ENDITEM,
"Name=seatPref", "Value=None", ENDITEM,
"Name=seatType", "Value=Coach", ENDITEM,
"Name=findFlights.x", "Value=48", ENDITEM,
"Name=findFlights.y", "Value=8", ENDITEM,
"Name=.cgifields", "Value=roundtrip", ENDITEM,
"Name=.cgifields", "Value=seatType", ENDITEM,
"Name=.cgifields", "Value=seatPref", ENDITEM,
LAST);
//订票事务结束
lr_end_transaction("order",LR_AUTO);
return 0;
}
实现自动化操作
主要就是要会创建参数源,然后会调用
创建参数源
选中脚本中你想要用常量替代的变量,右键选择replace with parameter的create new parameter/Parameter List
在parameter设置参数列表,即参数源
添加数据行、设置参数选择模式、选择存放参数源文件类型、数据更新模式、**模拟运行情况查看(图中Simulate Parameter、可以运行多次模拟多用户操作后的结果,)**等
Generall下的runlogic:设计脚本循环运行次数。
init和end只运行一次,其他脚本文件收到次数设置影响
**General下的Pacing:**设置多个脚本之间的间隔时间,
General下的Log,日志需要自己开启
General下的ThinkTime,LR默认忽略思考时间,而实际场景不能进行忽略。
往下依次
Internet Protocol的设置检查点(web_reg_find())
General下Miscellaneous脚本运行错误方式,依次是
LR对于虚拟用户Vuser一般采用的是线程运行的,这些线程会共享父驱动器进程的内存段,可以取消多次重新加载驱动程序的必要,节省大量空间,允许程序在一个负载生成器上运行更多的Vuser虚拟用户。
LR如果采用进程方式运行每个Vuser,那么对于每一个虚拟用户都会启动一个mdrv进程。而在性能测试过程中,如果反复启动同一种驱动程序会占用大量随机存储器RAM和其他系统资源,造成浪费。
所以线程运行相较于进程运行支持更多并发用户,但是进程操作才能真实模拟用户操作,
可以选择成进程方式运行对订票系统进行性能测试,然后去windows资源管理器里看一眼服务器进程下面存在的mmdrv线程与Vuser的比较,如下图
LR选择进程运行和线程运行的位置
针对系统某一个指标的性能测试系统自带设置就能满足,但是系统全方位性能测试则一定使用手工设计场景
Controller除了支持LR脚本外,还支持其他单元测试脚本
场景模式选择:Controller分为手工场景模式和目标导向场景模式
对于手工场景设计,我们可以操纵很多元素进行设计。
而目标导向只要设定一个目标就可以,但是无法设置集合点
目标导向型场景只有如下几个目标,可以进行限制
主讲手工场景设计
针对5w原则进行场景设计
负责Controller不负责测试,将远程的LR Generator分配给指定的测试脚本
Controller会将每一个存放进来的脚本看成一个组,但是运行方式分为场景和组运行
按照场景(Scenario)运行,无论场景中导入多少脚本,所有脚本接受统一调度运行**(要注意如果测试用例之间存在依赖关系,一定要采用group方式运行)**
按照群组(group)运行,场景中脚本按照各自设计的运行方式运行
分组模式下支持对每个脚本进行运行顺序设定,有助于脚本之间的相互依赖
设置脚本运行顺序只能在群组Group模式下,加压减压策略也是在Group模式下
目的:使同一台主机的虚拟用户在发送请求时更加真实有效
为什么需要IP欺骗
当某个IP访问过于频繁或者访问量巨大,服务器出于自身安全考虑有时会拒绝该IP的访问
一些网站会限制同一个用户使用同一个IP进行登录,用于模拟真实使用环境
某些服务器采用了负载均衡配置,使用同一个IP地址不能测试实际性能
(win11使用ip wizard时ipconfig不会出现虚拟ip,原因还在查,使用LR暂时不要用11)
设置网虚假IP后再Controller让其生效,ip地址运行类型必须与脚本虚拟用户类型保持一致,线程用线程,进程用进程。如果成功后去查看随机一个虚拟用户日志时都能看到日志显示的ip地址是不一样的。
用户状态详解
可用常见资源列表详解Available Graphs,依次标注解释
Runtime Graphs运行时图(虚拟用户运行时状态展示):虚拟用户统计,用户定义数据点、错误统计、虚拟用户错误统计
**Transactions Graph事务图(运行过程中场景的事务运行状态):**事务响应时间、每秒通过事务、每秒没通过事务(错误或终止等)、每秒总事务数
Web Resource Graphs网页资源图(表现web测试中重要的数据图):每秒点击数、吞吐量、每秒http响应数量、网页安全字、每秒下载页面数、页面追踪数、连接数、每秒连接数、每秒执行SSL次数
**System REsource Graphs系统资源图(检查操作系统资源消耗,需要单独连接服务器测试):**windows资源监控,linux资源监控、snmp监控
Network Graphs网络资源图:监控网络延迟
web Server web服务器资源消耗监控:支持apache和IIS监控
性能测试最终一点是监控服务器的系统资源,监控cpu、硬盘、内存等进行说明。以windows为例。
两台电脑一台安装LR,另外一台被监控
被监控电脑操作
Controller可以直接打开analysis生成测试报告。
loadrunner入门篇 - Analysis 分析器 - 一加一 - 博客园 (cnblogs.com)
(4条消息) lr_Analysis结果分析工具_ka_ko的博客-CSDN博客
一般录制脚本和运行重发时打开Fiddler,然后Fiddler能正常使用就没有离谱问题出现
LoadRunner_2 错误 -27987: 找不到请求的图像 [MsgId: MERR-27987]_zdlulu
回放脚本超时,一般回放脚本时超过120s都会出现,我去晚上查有很多原因都会导致此错误出现。
通常是在运行环境里设置一下超时时间,提高120s,然后设置多迭代运行脚本几遍。
如果还有超时现象,需要在“Runtime Setting”>“Internet Protocol:Preferences”>“Advanced”区域中设置一个“winlnet replay instead of sockets”选项,再回放是否成功
没去勾选开启文本图像检查
Runtime Setting->perferences->enable image and text check
重装吧,安装有问题,最好去查查
Run-Time Setting → Internet Protocol →Preferences→Option →Step download timeout(sec)改为32000
翻译是发送响应失败,百度方法解决千篇一律都是在Runtime-setting中的preferences–>options–>http-request connect timeout(sec)的值设为999。
但是我没解决所以搜了一下
Loadrunner 并发时’Error -27492 HttpSendRequest failed’解决办法 - 牧羊神 - 博客园 (cnblogs.com)
小型网站最好不要用wininet代替LR发送请求,你是用windows的WinInet替代LR的请求发送,勾选后LR检查不到。一旦网站请求处理慢了,LR还检测不到,那你设置LR超时时间也自然没有用,对LR就是请求失败。
人家分析的很到位,是我上一次录脚本手欠勾选了winlnet replay instead of sockets(windows only),我对LR自带的订票系统太有信心了,而且Controller执行用户设置过多,电脑硬件还不行,网站崩了。
这种错误常常是因为并发压力过大,服务器端太繁忙,无法及时响应客户端的请求而造成的,所以这个错误是正常现象,是压力过大造成的。如果压力很小就出现这个问题,可能是脚本某个地方有错误,要仔细查看脚本,提示的错误信息会定位某个具体问题发生的位置
翻译是发送响应失败,百度方法解决千篇一律都是在Runtime-setting中的preferences–>options–>http-request connect timeout(sec)的值设为999。
但是我没解决所以搜了一下
Loadrunner 并发时’Error -27492 HttpSendRequest failed’解决办法 - 牧羊神 - 博客园 (cnblogs.com)
小型网站最好不要用wininet代替LR发送请求,你是用windows的WinInet替代LR的请求发送,勾选后LR检查不到。一旦网站请求处理慢了,LR还检测不到,那你设置LR超时时间也自然没有用,对LR就是请求失败。
人家分析的很到位,是我上一次录脚本手欠勾选了winlnet replay instead of sockets(windows only),我对LR自带的订票系统太有信心了,而且Controller执行用户设置过多,电脑硬件还不行,网站崩了。
这种错误常常是因为并发压力过大,服务器端太繁忙,无法及时响应客户端的请求而造成的,所以这个错误是正常现象,是压力过大造成的。如果压力很小就出现这个问题,可能是脚本某个地方有错误,要仔细查看脚本,提示的错误信息会定位某个具体问题发生的位置