优品软件培育计划【第五期】—— 性能测试测试策略制定(下)
图片


优品软件培育计划百场前沿技术系列讲座直播的第五场邀请到的是负责参与过多项国家级性能测试项目的上海市软件评测中心高级测试工程师曹骏。他从用例设计、脚本编写、场景设置等方面带大家一起探究了性能测试策略的制定。现将整场讲座的内容整理如下,供大家继续学习使用。


图片

-正文-

05

测试脚本编写


性能测试脚本的编写可以按照下图的几个步骤来进行
 
图片
 
首先我们通过LoadRunner去录制一个Vuser的脚本,然后我们针对脚本进行编写,整个步骤的核心环节也在此。编写好脚本后配置运行时的设置,单独的模式去运行这个Vuser脚本,也就是回放一下,当脚本回放可用时,将这个脚本集成到LoadRunner的测试方案中。
 
接下来跟大家分享几个在编写脚本时比较常用也是比较有用的几个操作。
 
◆定义事物


事务(Transaction)是这样一个点,为了衡量某个action的性能,需要在action的开始和结束位置插入这样一个范围,这就定义了一个transaction。


LoadRunner 运行到该事务的开始点时,LoadRunner 就会开始计时,直到运行到该事务的结束点,计时结束。这个事务的运行时间在结果中会有反映。


在录制脚本的过程中,需要将关注的每个业务逻辑单位标记为事务并进行命名,这样可以在统计结果得到更多的分析数据并可以直接统计各个功能点对整体性能的影响。
 
◆添加校验


对于某些关键功能以及LoadRunner自动增加的校验不能够满足要求时,需要增加检查点,判断在指定点上是否由指定的数据或者元素返回。


同时当出现脚本修改完成后无法回放或者并发过程中出现业务操作没有按照实际情况执行,那么很有可能是LoadRunner忽略了运行阶段的错误,此时,也需要增加检查点来规避排查。
 
◆集合点


集合点是一个并发访问的点,集合点经常和事务结合起来使用,常放在事务的前面。


在正常的一般的性能测试过程中,不需要使用集合点,因为使用结合点得到的性能曲线将是成锯齿状,而不是相对平滑的波浪线,同时在实际的生产环境中同时并发的用户也不会是在同一个操作上的并发。


这个主要是因为集合点的排队机制,加载到集合点的用户并不会继续操作下去,而是等待后面用户完成,而后面完成的用户的并发数,就不是实际的并发数了,最后得到的结果也会产生一些偏差。理论上是会更好一点,但这不是我们需要的结果。
 
使用集合点只是对关键功能或者处理逻辑复杂、响应时间长的关键业务点以及需要严格并发来确定是否存在并发问题的等情况下进行使用。
 
接下来我们通过实际的脚本去看一下检查点和集合点的具体应用,下面这个图是一个已经录制编辑好的界面,它录制的操作是用户登录之后进入主页面,新增一个文档,再删除一个文档的操作。我们需要测试的操作只有新增和删除的操作,所以我们就把其他一些无关紧要的,包括登录、进入页面以及注销的操作放在init和end中,因为这些不是我们关心的一些功能操作。然后我们将新增和删除的操作尽量精准地录制到Action中。尽量精简是什么概念呢?在新增这个页面只是将“提交”这个操作放在Action中,而之前说的那些新增页面的操作放到了init里面,如果它没有关联的话。在进行了数据参数化及关联这些操作之后,保证这个脚本是可用的之后,我们可以通过添加事务集合点以及校验来进一步增强这个脚本。
 
首先我们用事务区分开新建文档和删除文档这两个操作,我们将这两个操作的最后一步点击分别设置成“新建文档”和“删除文档”的transaction,然后在所有的transaction前面都设置好集合点,这样就能保障所有的事务都能以预期的并发数进行性能测试。
 
我们以下图这个脚本为例,有的人会认为新建文档在Action开始的时候就是在执行的事务,它一开始就是以并发的状态进行的操作,那么就不用添加集合点了,这种说法是不对的。不添加集合点的话,虽然第一次迭代的时候保证的是你预期的并发数,但是你后面的每一次迭代可能会由于用户的排队机制的问题导致并不是所有的用户都是同时在进行并发,有的是在等待。因此后面的操作就不一定是以这个并发数来操作了。所以针对我们需要关注的所有的事务前面都是需要加一个检查点的,不管它是在脚本里的什么位置。
 
图片
 
下面的图是后半段,针对删除操作我们同样也定义了它的事务,在事务的前面我们加上了集合点,去保障它的并发数。最后在里面添加了一个针对删除的返回信息的校验,去看一个文档被成功删除后的提示信息,校验它删除是否成功。如果有这个提示信息就代表它成功了,如果没有这个信息就代表它失败了。在进行了这些操作之后,我们就将原本操作中我们需要验证的内容以事务的形式标识出来,然后再加入集合点和校验来保证并发以及操作的正确性。
 
图片

这样就可以有效针对相应的测试需求去编辑并增强脚本了,这个脚本也是可用的。

在LoadRunner里面有一块我们需要特别说明一下,当你使用http协议录制脚本的时候,你是可以选择html格式录制,也可以选择url模式录制,这两种模式是有区别的,url模式脚本的代码量会比较多,而html模式,是针对一系列的操作,比如说他是占一个点击,然后将这个点击的所有操作、抓取到的的资源都整合成一个完整的请求,相对于url模式代码量看起来就比较少,界面也更加简洁一点。
 
但是有这样一种情况,如果一个页面存在页面缓存机制的话,我们使用url模式录制的时候,会比较真实地反映资源的加载,它就不会加载那些已经缓存过的资源。但是如果用html模式录制的话,因为它是针对整个请求的一个整合,由于机制的一个原因,多次迭代之后,它会反复加载那些已经缓存了的资源。这样最终的性能测试结果html模式录制的就会比url模式录制的回放时间长,性能结果也会更长。
 
图片
 

06

实际运行场景的设置


录制完脚本之后,我们就进行实际运行场景的设置
 
我们可以把脚本集成到LoadRunner里,下面的页面就是道普云的测试方案的一个具体界面。左边是导入的脚本,右边是我们设置的性能测试的场景策略。
 
图片
 
选择不同的测试方法就需要设置不同的运行场景,现在主要的场景主要有单业务场景和混合业务场景。
 
单业务场景策略:重点针对单个业务进行性能测试。
 
混合业务场景策略:根据在线业务进行统计信息收集,保证所有的在线业务同时进行操作,每种业务按照业务数据量比例和业务操作的频率比例进行设置,从业务的多样性上来模拟实际的生产环境。相当于同时运行多个功能,每个功能分配不同的并发用户数。
 
不管是单业务场景还是混合业务场景,我们在进行场景测试的同时,都是可以监控服务器的一些技术信息的通过这些数据对服务器进行综合性能分析,找出系统瓶颈,为调优或者提高性能提供依据。
 
针对测试策略中的加压策略,我们介绍两种不同的加压策略。
 
图片
 
Flat测试是所有的用户一次性加载完,并且是在预期的时间内持续地运行。
 
Ramp-up测试并发用户数是逐步上升的,几秒增加一部分用户数,在一段时间内才达到最大的并发用户数,持续运行一段时间后,再把它释放掉。
 
Flat测试的优势在于它可以产生精确且可以重现的平均值,Ramp-up测试的优势是,可以看出随着系统负载的改变,测试量是如何改变的,可以根据这个选择以后要运行的Ramp-up测试的一个范围。
 
Flat测试也有一个问题,它最后会出现系统波动的一个结果。下面这4张图显示的是一次flat测试中得到的系统吞吐量、cup占用率、执行对列长度以及事务的平均响应时间。我们可以看到这4张图上都出现了波动的情况,其实当测试中所有的用户都执行相同操作的时候,就会发生这种情况。
 
图片

有两种方法是可以从这个类型的结果中获取精确的测量值的,一种是,如果测试可以运行相当长的一个时间,那么它的随机事件的本性使然,他的服务器的吞吐量就会拉平,曲线也会更平滑。或者我们可以选取波形中两个平息点之间的测量值,这个方法存在一个明显的缺点,获的数据的时间就会非常短。
 
Flat测试和Ramp-up测试是各有优势的,下面我们就通过介绍几种实用的性能测试策略来分析这两种加压策略的着重方向。
 
基准测试


基准测试是一种测量和评估软件性能指标的活动,通过基准测试建立一个已知的性能水平(称为基准线),当系统的软硬件环境发生变化之后再进行一次基准测试以确定这些变化对性能的影响。因此基准测试的关键是要获得一致的、可再现的结果。


可再现的结果有两个好处:
减少重新运行测试的次数
对测试的产品和产生的数字更为确信
 
从这里我们可以看到flat测试是基准测试的一个理想模式,我们平时在LoadRunner的场景设置里我们就可以考虑将Think Time和Pacing Time设置为0。这样我们就可以通过flat测试区获得一个准确的基准线,通过并发后得到的响应时间、吞吐量以及服务器资源占用的这些数据就能更有效地观察系统当前的性能水平。
 
规划测试:
 
在特定的环境下,给定应用程序的性能可以达到何种程度。


可重现性就不如在基准测试中那么重要了,因为测试中通常都会有随机因子。


例如:知道普通用户的考虑时间是5秒,误差20%,那么在设计负载测试时,就要确保不同请求间的时间(ThinkTime)为5X(1+/-20%)秒。此外可以利用调步的理念向负载场景中引入更多的随机性。即在一个虚拟用户完成一整套的请求后,该用户暂停了一个设定的时间段,或者一个小的随机时间段(PacingTime),例如2X(1+/-25%)秒,然后再继续执行下一套请求。将这两种随机变化方法运用到测试中,可以提供更接近于现实世界的场景。
 
LoadRunner里面的设置页面如下图所示:
 
图片
Think Time的设置 
 
图片
Pacing Time的设置

规划测试我们如何加载用户以模拟负载情况呢?是使用Flat测试还是使用Ramp-up测试呢,其实最好的方法是模拟一个高峰时间用户与服务器通讯的情况,如果用户的负载情况是在一段时间内逐步达到的,那么就应该用Ramp-up测试,每隔几秒增加多少个用户,如果他的用户是在非常短的时间内同时与系统通信的,那么这样的话我们就需要用Flat测试,将所有的用户同时加载到服务器上。这种情况相当于电商平台的秒杀操作,但是它一般只进行一次大规模的并发操作,后面几次迭代就不一定是相同的并发数了。
 
渗入测试(疲劳强度测试)


使用固定数目的并发用户测试系统的总体健壮性。
 
这是比较简单的一种性能测试,深入测试的特点是需要的时间较长,而且使用固定数目的并发用户。这类测试会通过内存泄露、增加的垃圾收集机制或者系统的其他问题显示因长时间运行而出现的任何性能的降低的结果。系统运行的时间越久,它显现的情况就越明显。我们可以运行两次摄入测试,一次是使用较低的用户负载,一次是使用较高的用户负载,这样结果会更有对比性。测试要运行较长的时间,如几天,以便真正了解应用程序的长期健康状况。
 
要确保测试的应用程序尽可能接近现实世界的情况,用户场景也要逼真(虚拟用户通过应用程序导航的方式要与现实世界一致),因此应该采用混合业务测试场景的测试策略,从而测试应用程序的全部特性。
 
确保运行了所有必需的监控工具,以便精确地监测并跟踪问题。
 
峰谷测试
 
峰谷测试兼有容量规划ramp-up类型测试和渗入测试的特征。


其目标是确定从高负载(例如系统高峰时间的负载)恢复、转为几乎空闲、然后再攀升到高负载、再降低的能力。


实现这种测试的最好方法就是,进行一系列的快速ramp-up测试,继之以一段时间的平稳状态(取决于业务需求),然后急剧降低负载,此时可以令系统平息一下,然后再进行快速的ramp-up;反复重复这个过程。
 

■ 总结 


下面是一张性能测试的流程图,一开始性能测试启动后,我们需要根据项目的情况去确定性能测试的需求,确定了需求之后,我们根据需求去准备相应的测试环境,在环境上部署相应的性能监控,根据需求录制编辑并增强性能测试脚本,根据脚本的内容准备好性能测试需要的一些测试数据,在脚本里做好参数化的工作,这些准备好之后,就需要设置相应的测试场景,到此为止就是一个完整的性能测试策略的制定的过程。


图片

根据这样一个性能测试策略执行出来的结果就可以比较直观可信地反映出系统的性能测试的一个整体表现。



图片

下期介绍


下期直播将在下周举行,由田超为大家带来安全测试相关方面的讲座,他从事软件测试、维护及管理工作十余年,现就职于全球著名手机厂商,担任QA Leader职务。具体直播信息将在直播前通过微信公众号或社群进行通知,请大家随时关注。