关于性能测试及相关问题的探讨 软件测试
一、性能测试概念
性能测试是一个较大的范畴,包括负载测试、压力测试和容量测试。其中负载测试是为了检验系统在给定负载下是否能达到预期性能指标;压力测试是通过不断向被测系统施加“压力”,测试系统在压力情况下的性能表现;容量测试针对数据库而言,是在数据库中有较大数量的数据记录情况下对系统进行的测试。
二、性能测试前的环境检查
PETE(PErformance TEst的前2个字母的缩写,即性能测试)前的检查工作看似简单,然而其必要性和重要性都值得关注,避免在调试那很久软件参数,抓落那n把头发的时候,结果却发现硬件条件早就不能支撑,白白耽误时间,而Software Developer自己做PETE的时候(至少我是),最容易忽视的就是硬件。
[硬件检查]
1.Check CPU,MEM of all the test objects
2.Check Storage efficiency : multipath -ll; hdparm -Tt /dev....
3.Check Network using tools like iperf
[软件设置]
1. 线程不是越多越好,线程切换,资源锁等因素的影响使得性能的提升和线程的数目之间不会是一个正相关,特别是线程的数目达到一定的值以后,更多的线程可能反而帮那倒忙。
最好是先根据系统整体输入,各个模块的输入,模块内部线程对输入消息的处理模型:阻塞,非阻塞,同步异步等等,对线程数目做一个预估计,然后在这个值的基础上进行调整,不然在多进程,多线程的架构下面,单单靠试错的方法,很可能按下葫芦浮起瓢,如此多的调整参数,非把人搞疯不可。
2. 理清楚系统内部的一个性能瓶颈所在之处,完全靠PETE的结果来反映是不现实的,一是需要比较长时间PETE的结果来梳理出结果,耗时;二是很可能系统的设计让消息在各个模块里的处理时间完全不可见,缺少像transaction(Glance arm)的runtime统计支持,当然也可以不使用工具,自己造轮子比如对于每个消息用唯一的ID号标记,同时在模块的输入和输出的时候对消息做事务日志(event log),支持这种log的开关可配置,既方便调试,也可以在部署到客户关闭。有的同学说那,也可以使用宏开关,对于实验室版本和发布版本分别打开或者关闭,那就是具体问题具体分析那嘛。
3.当你在使出浑身解数,把所有可调的东西全调那n次以后,还是对PETE测试结果非常不满意,性能提升完全毫无希望,哎,还是重新考虑架构是否合理吧,选择的库性能是否经过测试,虽然这些一开始的时候就应该考虑到,怎么说呢,一开始就能考虑到的估计已经是走出软件作坊的吧。
三、性能测试的关键因素
自动化测试系统存在三个关键因素:语言、驱动程序和测试工具。您编写测试用例及扩展测试系统时都需用用到语言,所以编程语言曾一度令我着迷,如 Perl、Python 和 Ruby。而且我还发现测试人员往往更能将各种编程语言运用得得心应手。尽管我有充分的理由偏爱 Ruby,但是其他一些较好的自动化测试系统却使用的是其他的编程语言。事实上在过去的几年里,我用过 Perl、Python 和 VB 建立测试框架,因为这些通常是客户端已使用的语言。另外,相比商用测试工具套件常使用的私有语言,我更侧重使用全功能的编程语言,可能因为我对私有语言已失去了耐心。
选择语言的范围很广,但是寻找一个合适的驱动程序就相对困难很多。驱动程序是用于您应用程序驱动的,就像 Watir 是一款浏览器的驱动程序,适用于网络应用程序的驱动。驱动程序可以对语言的选择起到决定性作用。几年前,我针对命令行应用程序使用的驱动是 Expert,其相对应的语言是 TCL,所以对应的工具套用的也是 TCL 语言。我开发 Watir,是因为我想用 Ruby 的浏览器驱动程序。使用 Ruby 的 Watir 是我们针对网络应用程序测试的解决方案。
测试系统的第三个关键因素即测试工具,它主要负责执行测试用例,以及收集、报告结果。在我们开发初期,我们都是用 Test::Unit,这是一个基于 Ruby 的测试工具,可用于单元测试,同时也可用于功能测试。近期,也有些 Watir 用户开始使用 Rspec 或 Cucumber,但是也有些人不喜欢使用现有的测试工具,而更喜欢自己构建。
我是在开发商用测试工具套件(如 SilkTest 和 WinRunner)时有的这些认识。尽管这些套件包经常被认定为工具,但我发现他们实际上是压缩了一系列的集成工具。它们的使用预期往往不能满足测试人员的实际需求。就像数据驱动测试期间,我们需要打散原有的套件,然后按一种更加合理的配置重新组装。所以我需要测试人员对测试系统内每个单独的工具都能清楚地了解。
许多新的 Watir 使用者在区分 Watir(驱动程序)结点和 Ruby(语言)起点时会有困难,这是因为他们对这两者的功能未能清楚地理解。我得知一些教 Java 的老师不喜欢学生去使用 IDE(如 Eclipse 或 Netbeans),而更希望他们能学习使用一些需要的工具,如编辑工具和压缩工具,以了解它们的功能。同样的,我也希望测试人员能更清楚地了解测试系统内不同工具和部件的功能。
一些新的 Watir 使用者经常会来问一些问题,而这些问题的答案很明显是我们已经获知的。Watir 是否可以读 CSV 文件?Watir 是否可以进行日期运算?Watir 是否可以从数据库读取数据?对于这些问题的答案都是否定的,Watir 不能做到这些,但是 Ruby 却能做到。任何浏览器驱动程序都不能完成这些操作(就像您的压缩软件不支持搜索和替换),但是任何全功能的编程语言却能做到。因为测试人员习惯使用的是商用工具套件,这些套件所包含的系统是封闭的,所以他们在使用 Watir 初期可能会提出这样的问题。但实际上您无需担心 Watir 是否缺少某些功能,您只需具备的使用这些功能的能力,一旦供应商将这些功能加入套件包内,即能马上熟练运用。Watir 是一个开发式系统的一部分,经常会有非 Watir 社区的人员对现有的库进行完善,他们可以说是属于一个更大的 Ruby 社区的人员。
四、性能测试工具--LoadRunner的结构和原理
LoadRunner是 Mercury Interactive的一款 性能测试 工具,也是目前应用最为广泛的性能测试工具之一。该工具通过模拟上千万用户实施并发负载,实时性能监控的系统行为和性能方式来确认和查找问题。
(一)、 LoadRunner 工具组成
1、虚拟用户脚本生成器:捕获最终用户业务流程和创建自动性能测试脚本,即我们在以后说的产生测试脚本;
2、压力产生器:通过运行虚拟用户产生实际的负载;
3、用户代理:协调不同负载机上虚拟用户,产生步调一致的虚拟用户;
4、压力调度:根据用户对场景的设置,设置不同脚本的虚拟用户数量;
5、监视系统:监控主要的性能计数器;
6、压力结果分析工具:本身不能代替分析人员,但是可以辅助测试结果的分析。
(二)、LoadRunner工作原理
代理(Proxy)是客户端和服务器端之间的中介人,LoadRunner就是通过代理方式截获客户端和服务器之间交互的数据流。
1)虚拟用户脚本生成器通过代理方式接收客户端发送的数据包,记录并将其转发给服务器端;接收到从服务器端返回的数据流,记录并返回给客户端。
这样服务器端和客户端都以为在一个真实运行环境中,虚拟脚本生成器能通过这种方式截获数据流;虚拟用户脚本生成器在截获数据流后对其进行了协议层上的处理,最终用脚本函数将数据流交互过程体现为我们容易看懂的脚本语句。
2)压力生成器则是根据脚本内容,产生实际的负载,扮演产生负载的角色。
3)用户代理是运行在负载机上的进程,该进程与产生负载压力的进程或是线程协作,接受调度系统的命令,调度产生负载压力的进程或线程。
4)压力调度是根据用户的场景要求,设置各种不同脚本的虚拟用户数量,设置同步点等。
5)监控系统则可以对 数据库 、应用服务器、服务器的主要性能计数器进行监控。
6)压力结果分析工具是辅助测试结果分析。
第一步:从分析Summary的事务执行情况入手
Summary主要是判定事务的响应时间与执行情况是否合理。如果发现问题,则需要做进一步分析。通常情况下,如果事务执行情况失败或响应时间过长等,都需要做深入分析。
下面是查看分析概要时的一些原则:
(1):用户是否全部运行,最大运行并发用户数(Maximum Running Vusers)是否与场景设计的最大运行并发用户数一致。如果没有,则需要打开与虚拟用户相关的分析图,进一步分析虚拟用户不能正常运行的详细原因;
(2):事务的平均响应时间、90%事务最大响应时间用户是否可以接受。如果事务响应时间过长,则要打开与事务相关的各类分析图,深入地分析事务的执行情况;
(3):查看事务是否全部通过。如果有事务失败,则需要深入分析原因。很多时候,事务不能正常执行意味着系统出现了瓶颈;
(4):如果一切正常,则本次测试没有必要进行深入分析,可以进行加大压力测试;
(5):如果事务失败过多,则应该降低压力继续进行测试,使结果分析更容易进行;
......
上面这些原则都是分析Summary的一些常见方法,大家应该灵活使用并不断地进行总结与完善,尤其要主要结合实际情况,不能墨守成规。
第二步:查看负载生成器和服务器的系统资源情况。
查看分析概要后,接下来要查看负载生成器和待测服务器的系统资源使用情况:查看CPU的利用率和内存使用情况,尤其要注意查看是否存在内存泄露问题。这样做是由于很多时候系统出现瓶颈的直接表现是CPU利用率过高或内存不足。应保证负载生成器在整个测试过程中其CPU、内存、带宽没有出现瓶颈,否则测试结果无效。而待测试服务器,则重点分析测试过程中CPU和内存是否出现了瓶颈:CPU需要查看其利用率是否经常达到100%或平均利用率一直高居95%以上;内存需要查看是否够用以及测试过程是否存在溢出现象(对于一些中间件服务器要查看其分配的内存是否够用)。
第三步:查看虚拟用户与事务的详细执行情况。
在前两步确定了测试场景的执行情况基本正常后,接下来就要查看虚拟用户与事务的执行情况。对于虚拟用户,主要查看在整个测试过程中是否运行正常,如果有较多用户不能正常运行,则需要重新设计场景或调整用户加载与退出方式再次进行测试。对于事务,重点关注整个过程的事务响应时间是否逐渐变长以及是否存在不能正常执行的事务。总之,对每个用户或事务的执行细节都应该认真分析不可轻易忽略;
example1:一个性能逐步下降的服务器,需要进一步分析其性能下降的原因【可以查找是否存在内存泄露问题】;
example2:一个性能相对稳定的服务器,但是响应时间偏大,这时需要分析程序算法是否存在缺陷或服务器参数的配置是否合理。
第四步:查看错误发生情况。
整个测试过程中错误的发生情况也应该是分析的重点。下面是查看错误发生情况的常用准则:
(1)查看错误发生曲线在整个测试过程中是否是有规律变化的,如果有规律通常意味着程序在并发处理方面存在一定的缺陷。
(2)查看错误分类统计,作为优化系统的参考。例如对于Web性能测试,当出现瓶颈时往往需要查看服务器的错误统计信息结果:如果“超时错误”占到90%以上,可能需要提高硬件配置;如果较多的“内部服务器错误”,则可能是程序方面存在问题。
文章来源于领测软件测试网 https://www.ltesting.net/