随着互联网产品的普及,产品面对的用户量级也越来越大,能抗住指数级增长的瞬间访问量以及交易量是保障购物体验是否顺畅的至关重要的一环,而我们的性能测试恰恰也是为此而存在的。 性能测试是什么呢?性能测试要怎么测呢?为什么要开展性能测试呢?今天的内容由上海市软件评测中心高级测试工程师曹骏带来,他曾参与负责过浙江省交通运输厅“区域物流资源共享服务平台研发和应用”国家科技支撑计划课题、1号店电商平台商家商务诚信体系建设项目、上海市工业能效大数据分析研究与平台建设项目等多项国家级、市级、区级项目课题。以下是正文内容:
我们平时接触的大部分性能测试其实用一句话去概括就可以了:通过一个设计好的性能测试有效定位系统的瓶颈,从而有目的地、有针对性地对系统进行调优。因此性能测试测试策略的制定就是性能测试中非常重要的一环。 接下来会从以下几个方面去展开:性能测试的目的、性能测试的类型、常见问题概述、测试需求理解以及计划制定、测试脚本编写、实际运行场景的设置、最后综合以上几点进行一下总结。
一、性能测试的目的
性能测试的目的其实就是为了验证软件系统是否能够达到用户的性能指标,发现软件系统中存在的性能瓶颈,随后优化软件,最后起到优化系统的目的。主要有以下几点:
1、评估系统的能力
测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策。
2、识别体系中的弱点
受控的负荷可以被增加到一个极端的水平,并突破它,从而修复体系的瓶颈或薄弱的地方。
3、系统调优
重复运行测试,验证调整系统的活动得到了预期的结果,从而改进性能。
4、检测软件中的问题
长时间的测试执行可导致程序发生由于内存泄露引起的失败,揭示程序中的隐含的问题或冲突。
5、验证稳定性&可靠性
在一个生产负荷下执行测试一定的时间是评估系统稳定性和可靠性是否满足要求的唯一方法。
二、性能测试的类型
为了达到性能测试的目的,需要通过不同的性能测试策略来实现,而性能测试的测试策略又基于不同的性能测试的类型。接下来就给大家介绍一下最常见的性能测试类型:
1、负载测试
负载测试是测试软件在各种不同负荷下的表现。在这种测试中,将使测试对象承担不同的工作量,以评测和评估测试对象在不同工作量条件下的性能行为,以及持续正常运行的能力。
负载测试的目标是确定并确保系统在超出最大预期工作量的情况下仍能正常运行。此外,负载测试还要评估性能特征,例如,响应时间、事务处理速率和其他与时间相关的方面。
2、压力测试
压力测试是为了发现系统性能在可以接受的范围内能支持的最大负载的测试,是对系统不断施加压力的测试,是通过确定一个系统的瓶颈或者不能接受的性能点,来获得系统能提供的最大服务级别的测试。例如测试一个 Web站点在大量的负荷下,何时系统的响应会退化或失败。
3、基准测试
基准测试是一种测量和评估软件性能指标的活动,通过基准测试建立一个已知的性能水平(称为基准线),当系统的软硬件环境发生变化之后再进行一次基准测试以确定这些变化对性能的影响。
4、疲劳强度测试
疲劳强度测试是采用系统在要求支持的最大并发用户数情况下持续执行一段时间,通过综合分析交易执行指标数据和系统资源监控数据来确定系统处理要求最大工作量强度性能的过程,以验证系统是否能够稳定运行。
5、大数据量测试
大数据量测试主要针对数据库有特殊要求的系统进行的测试,可以分为实时大数据量测试和极限状态下的测试。实时大数据量测试主要目的是测试用户较多或者某些业务产生较大数据量时,系统能否稳定运行;极限状态下的测试,测试系统使用一段时间即系统累计一定量的数据时能否正常的运行业务。
三、性能问题常见特征
性能测试的类型其实不仅仅只有这五种。在系统使用的过程中,往往会遇到不同的性能问题,在这里我们总结一下常见的性能问题的六个特征:
1、持续缓慢:应用程序一直特别慢,改变负载,对整体响应时间影响很少
2、随着时间推进越来越慢:负载不变,随着时间推进越来越慢,可能到达某个阈值,系统被锁定或出现大量错误而崩溃
3、随着负载增加越来越慢:每增加若干用户,系统明显变慢,用户离开系统,系统恢复原状
4、零星挂起或异常错误:可能是负载或某些原因,用户看到页面无法完成并挂起,无法消除
5、可预见的锁定:一出现挂起或错误,就加速出现,直到系统完全锁定。通常重启系统才解决
6、突然混乱:系统一直运行正常,可能是一个小时或三天之后,系统突然出现大量错误或锁定 当这些问题出现的时候,往往需要通过性能测试去寻找这些问题的成因,以此来制定相应的解决方法。
比如,持续缓慢可能是中间层的一些问题,也有可能是web系统或者web瓶颈的一些问题,或者是代码拼写得过于糟糕导致的。随着负载增加越来越慢可能是服务器资源的一些原因。零星的挂起或异常错误可能是因为内部资源过度使用或者分配不足导致的。可预见的锁定和突然混乱都可能是后端系统的宕机或者网络原因造成的。
这些都是可以通过制定性能测试的策略去进行定位的。
前面我们大体讲了下什么是性能测试,为什么要进行性能测试以及怎样进行性能测试,就是what、how、why的一个思路,接下来我们通过实际流程的操作,来针对性能测试中测试策略的制定去做一个详细的讲解。
四、测试需求理解以及计划制定
首先我们需要先明确测试的需求,而定位需求需要确认两点,一个是测什么?一个是测多少?而测什么就是性能测试的测试场景。
针对测试场景来说,有明确的性能需求要求,按照要求确认测试内容即可。但是大多时候我们的测试是没有明确的测试需求的,那可以利用以下几种方法。
根据系统运行背景(如系统类型、运行环境、用户数等);在关键功能中选择不超过10%的用户最关注、最重要的业务功能,作为性能测试的测试场景。打个比方,一个电商网站,测试场景就是一个用户搜索商品、加入购物车、提交订单这块重点来做,而我们不会把重点放在后台管理那些操作上。
测多少其实就是每一个测试场景所对应的并发用户数。有明确的并发用户数要求,则按照要求确认并发用户数。没有明确的并发用户数要求时,建议大家分析系统上线使用时的终端用户数量,按照终端用户数的10%以上作为性能测试的并发用户数。而当我们无法确认上线后的终端用户数量有多少时,建议并发用户数从最少取50个取起,然后慢慢累加,以实际的情况去进行调整,也可以去参考同行业内的相关标准。
下面我们就拿几个例子去具体说明一下。
性能指标需求模型---二八模型
第一个标准是大家很熟悉的二八定律。它是19世纪末20世纪初意大利经济学家帕累托发现的。
他认为,在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%尽管是多数,却是次要的。 下面我们就以一个具体的案例去说明 某系统总容量达到日交易量15万笔,根据这一要求对系统进行性能测试并开发性能测试需求:
下面是计算的步骤:
采用2/8比例,即80%的业务在20%的峰值时间内完成,20%的业务在80%的非峰值时间内完成,那么可以得到峰值处理业务量15万的80%为12万,非峰值处理业务量15万的20%为3万。
1天系统运行时间为20小时,另4小时为非营业的后台处理时间,那么峰值时间20小时的20%为4小时,非峰值时间20小时的80%为16小时。 可以计算到:1)平均峰值处理速度12万/(4*3600)秒接近9个/秒;2)平均非峰值处理速度3万/(16*3600)秒约0.5个/秒;] 考虑到特殊情况的发生,建议实际峰值处理速度要能达到理论计算的平均峰值处理速度的1.5到2倍。
所以最终确定下来的建议峰值处理速度为9个/ 秒*2=18个/秒。
2-5-8原则
另外一个业内广泛使用的原则就是“2-5-8原则” 所谓的“2-5-8原则”,简单说,就是当用户能够在2秒以内得到响应时,会感觉系统的响应很快;当用户在2-5秒之间得到响应时,会感觉系统的响应速度还可以;当用户在5-8秒以内得到响应时,会感觉系统的响应速度很慢,但是还可以接受;而当用户在超过8秒后仍然无法得到响应时,会感觉系统糟透了,或者认为系统已经失去响应,而选择离开这个Web站点,或者发起第二次请求。
我们可以将258原则作为考量性能测试平均响应时间的一个标准。2秒是很快的标准,5秒也是可以的,8秒很慢但是可以接受,超过8秒的话就需要去定位一下瓶颈,去改进一下。 根据以上的测试需求及测试内容,我们就需要去制定相应的测试计划,将其转换成实际的工作量。
计划的制定需要根据以下几点:软件自身特点、用户对性能的关注程度以及项目周期、项目经费等。
具体内容包括:
测试时间:何时开始介入测试,测试周期
测试地点:测试环境、生产环境
测试内容:性能验证?故障诊断?性能调优?
所用测试方法
测试工具的选取
计划制定之后,在测试开始前,还需要一些准备工作,包括:测试环境、测试工具、测试数据和测试人员培训等。
展开来讲,首先性能测试环境搭建的基本原则主要有以下几点:
尽可能接近真实环境
营造相对简单、独立的测试环境
无毒的环境
考虑测试工具的安装条件
接下来针对测试环境我们还需要准备测试数据,主要包括:基本数据(如用户名、密码)历史业务数据、测试脚本中参数数据等。 如果生产环境中的数据足够多时,建议导入生产库数据作为性能测试的基础数据。
如果生产环境中的数据无、或者数据量不够需要手工生成数据时,建议批量生成有规律的数据作为性能测试的基础数据。
数据库在性能测试执行之前备份,在性能测试之后还原。可以减少脚本调试时间,从而缩短性能测试周期。 以上这些就是我们性能测试中需要做的一些准备工作,准备工作做好之后,我们就可以进行第一步测试脚本的编写。
五、测试脚本编写
性能测试脚本的编写可以按照下图的几个步骤来进行:
首先我们通过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模式录制的回放时间长,性能结果也会更长。
六、实际运行场景的设置
录制完脚本之后,我们就进行实际运行场景的设置 我们可以把脚本集成到LoadRunner里,下面的页面就是道普云的测试方案的一个具体界面。左边是导入的脚本,右边是我们设置的性能测试的场景策略。
如需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;反复重复这个过程。
■ 总结
下面是一张性能测试的流程图,一开始性能测试启动后,我们需要根据项目的情况去确定性能测试的需求,确定了需求之后,我们根据需求去准备相应的测试环境,在环境上部署相应的性能监控,根据需求录制编辑并增强性能测试脚本,根据脚本的内容准备好性能测试需要的一些测试数据,在脚本里做好参数化的工作,这些准备好之后,就需要设置相应的测试场景,到此为止就是一个完整的性能测试策略的制定的过程。
根据这样一个性能测试策略执行出来的结果就可以比较直观可信地反映出系统的性能测试的一个整体表现。
以上就是性能测试测试策略制定的全部内容,希望能够对您有所帮助。
(谢绝转载,更多内容可查看我的专栏)