第1章 自动化测试入门
软件测试在软件生命周期中占有很重要的位置,而且软件测试的工作量很大,根据有关研究,软件测试占整个软件项目工作量的40%~60%。所以,测试人员总怀有一个愿望,即由计算机自动完成测试的全部工作。产生这样的愿望是很自然的,因为当初发明计算机就是为了帮助我们完成各种各样的复杂计算,代替手工劳动。后来,计算机应用越来越广泛,例如帮助我们构建自动化生产线、数控机床和交通运输自动控制系统,计算机系统成为名符其实的自动化工具。软件是计算机系统的灵魂,当进行软件开发和测试时,我们很自然会产生自动化测试的想法。
自动化测试,简单地说,就是用软件测试工具来自动完成测试。我们也就是想用一个软件去操作和监控正在开发或将来要开发的软件,或者说先开发一个简单的软件工具,然后再用这个工具去检测一个又一个复杂的应用软件系统。这就是自动化测试最朴素的理想,想法简单、自然,但是,当我们深入下去,就会有很多问题要问自己,促使我们去思考,例如:
● 究竟什么是自动化测试?
● 自动化测试有什么优势?
● 自动化测试是不是投入很大?
● 如何选择测试工具?
如果把这些问题都想清楚了,就能够全面地、真正地理解自动化测试,将来能轻轻松松地实施自动化测试,实现自己的理想。
1.1 初识自动化测试
如果以前没有做过自动化测试,那么就不了解自动化测试,可能会觉得自动化测试比较神秘。但是,我们在日常的计算机操作中,可能会碰到一些自动化处理的过程,这些过程和自动化测试比较接近。下面两个简单的例子,可能对理解自动化测试会有所帮助。
1.1.1 自动化处理并不陌生
自动化处理过程,还是比较常见的,例如,在Windows操作系统的控制面板中,有一项功能——任务计划向导,可以预先安排一个定期自动执行的任务,如图1-1、图1-2所示,可以按照“每天、每周、每月、一次性或系统启动时、用户登录时”等方式来事先安排某些待执行的任务。等到事先设定的条件满足时,任务会被系统自动地执行。
图1-1 Windows自动执行任务的安排
图1-2 事先已安排好的任务
除了预定任务的安排和执行,DOS批处理文件也是一个很好的自动化处理的例子,直到今天的Windows Vista还在使用它。它更接近自动化测试,类似于后面介绍的自动化测试脚本。批处理文件中的命令行包括参数、判断条件、注释行、输入和输出等内容,如Apache启动的批处理文件,其代码如下。
apache_start.bat文件的内容 @echo off echo Diese Eingabeforderung nicht waehrend des Running beenden echo Bitte erst bei einem gewollten Shutdown schliessen echo Please close this command only for Shutdown echo Apache 2 is starting ... apache\bin\apache.exe if errorlevel 255 goto finish if errorlevel 1 goto error goto finish :error echo. echo Apache konnte nicht gestartet werden echo Apache could not be started pause :finish
概念
测试用例(test case)是为了特定测试目的(如检查程序是否出错或验证某个产品特性)而设计一个特定的使用实例或场景,包括测试条件、测试数据及与之相关的测试规程或操作过程。测试用例也可以被称为有效地发现软件缺陷的最小测试执行单元。
测试脚本(Test script)是进行自动化测试时所编写的、可执行的一种程序,以实现测试用例的执行过程。测试脚本一般由解释性的程序语言(脚本语言)来编写,如Perl、Tcl/Tk、Shell、Python、Ruby和Javascript等,也有一些测试工具特有的脚本语言,如类似于VB的SQABasic等。采用何种脚本语言是与测试工具相对应的。
1.1.2 一个简单的自动化测试过程
上述的自动化处理过程还不是测试,因为测试的重要一点是须要验证,将实际执行的结果和用户期望的结果进行比较。没有这个比较,就不是自动化测试。下面,让我们亲自动手完成一个简单的自动化测试过程,以便获得测试自动化的感性认识,进而揭开自动化测试的神秘面纱。
1. 下载和安装测试工具
首先去http://seleniumhq.org/projects/ide/下载Selenium IDE,点击右页上部的链接“download now”,下载其最近的一个版本(本书使用的是1.0 beta 2,2008年6月发布)。在安装Selenium IDE之前,要准备好Firefox(火狐)浏览器,Firefox可以从http://www.firefoxplus.org/下载。
安装Selenium IDE很容易。如果是用Firefox下载的,浏览器会自动提示安装,点击“立即安装”按钮就能完成安装。如果事先已下载类似“selenium-ide-1.0-beta-2.xpi”的文件,就用Firefox的“打开文件”菜单功能,打开已下载的xpi文件,安装Selenium IDE。安装成功后,重启Firefox,菜单“工具”下会出现“Selenium IDE”,如图1-3所示。
图1-3 FireFox工具菜单
点击“Selenium IDE”,启动Selenium IDE,出现主界面,可以展开左边测试用例(test case)列表窗口,默认是不展开的,展开后的界面如图1-4所示。左边测试用例的脚本直接显示在右边脚本窗口。这里只完成一个例子,可以合上左边窗口。
图1-4 Selenium IDE的界面
2. 录制测试脚本
打开Selenium IDE,默认处在录制状态。如果不是,就点击录制操作按钮。去Firefox打开Google首页www.google.cn,输入“用Selenium进行自动化测试”,点击“Google搜索”按钮,进入搜索结果页面,然后选择搜索结果页面中的“www.ibm.com”,点击右键,如图1-5所示,选择倒数第3项 “verifyTextPresnt www.ibm.com” ,验证“www.ibm.com”会在搜索结果中出现。
图1-5 对搜索结果进行验证操作界面
同样,选择“有9310项符合”和“搜索用时0.38秒”,进行同样的操作,即共进行3项验证。测试本身就是验证的过程,通过期望结果和实际结果比较,我们才能判断是否会出现缺陷。这里只是一个演示,所以简单地选择这3项内容作为将来验证的期望值。然后点击第1个搜索结果,结束录制,即点击按钮。录制的脚本可以在“脚本窗口”浏览,如图1-6所示。
图1-6 脚本录制完毕后的界面
3. 执行测试脚本
完成了脚本录制,就可以执行脚本(也称脚本回放)。先将回放速度调整慢些,从而使执行过程看得更清楚些,即将中绿色游标向“slow”移动。然后,点击按钮,就开始执行脚本。我们会看到浏览器自动打开www.google.cn的首页,自动输入“用Selenium进行自动化测试”,搜索结果页面很快显示出来,脚本执行结束。
4. 测试结果
运行结果如图1-7所示,从中可以看出,前面两个验证结果通过,显示为绿色,而第3个验证“verifyTextPresent搜索用时0.34秒”失败,显示为红色。为什么失败呢?因为Google每次搜索用时是不一样的,再次执行脚本的时候,用时只要0.04秒,会显示“搜索用时0.04秒”,导致第3个验证失败。查询日志(Log),可以看到红色的信息“[error] false”,说明验证失败。而且发现另一个操作,点击link也没成功,主要是链接页面已跳出基准URL(站点),不在Selenium IDE的控制范围。如果点击“高级搜索”链接,就没问题,你可以自己试试。这其中的原因,在第3章会做详细解释。
图1-7 运行结果界面(参见彩图1)
1.2 自动化测试和手工测试有什么不同
亲手做过上述的自动化测试之后,我们对自动化测试就有了一个感性的认识,至少有下列几点感觉:
● 自动运行的速度快,是手工无法比的。
● 测试结果准确。例如搜索用时即使是0.33秒或0.24秒,系统都会发现问题,不会忽视任何差异。
● 一旦脚本完成,可以一劳永逸地运行很多遍,重复使用。
从这里就可以初步体会到自动化测试的优越性——高效率、准确可靠和复用性。如果再展开讨论,我们就会发现自动化测试的更多益处。例如,手工进行测试会感觉累,而且一个人一天正常工作时间是8小时,最多工作十几个小时,而机器不会感觉累,可以不间断工作,每周可以工作7天、每天可以工作24小时。其次,计算机可靠,对同一个被测系统、用相同的脚本进行测试,结果是一样的;而手工测试容易出错,甚至有些用例没被执行,人可能有意无意出错。最后一点,有些手工测试做不到的地方,自动化测试却可以做到。例如,对一个网站进行负载测试,要模拟1000个用户同时(并发)访问这个网站。如果用手工测试,需要1000个测试人员参与,对绝大多数软件公司是不可能的。这时,如果让机器执行这个任务,假如每台机器能同时执行20个线程,只需要50台机器就可以了,而且启动之后,测试工具会自动运行和监控整个过程。
根据自动化测试的运行速度快、可靠、准确、从不疲惫和可多次重复使用等特点,可以知道——自动化测试有助于软件开发提高效率和产品质量、缩短周期、节省人力资源等。但同时也应看到,机器执行测试用例是按部就班进行的,没有变通的余地,缺乏创造力,而手工测试过程中,人具有创造性,容易受到前面操作或结果的启发,能举一反三,发现更多的问题。有资料显示,即使自动化测试实施良好,也只能发现软件系统中30%的问题,而70%的问题还要靠手工测试发现。所以自动化测试更适合于负载测试、性能测试和回归测试。
概括起来,通过自动化测试,软件企业可以获得许多好处。
● 测试周期缩短,因为自动化测试效率高、能够长时间不间断地运行。
● 完成更多的测试,实现更高的测试覆盖率,保证测试的一致性,提高测试的可靠性,最终获得更高质量的软件。
● 更高的测试团队士气,因为有更多机会学习编程、获取新技术;同时,自动化测试使测试工作变得更有趣。
概念
负载测试(Load Test),也称压力测试(Stress test)、强度测试。负载测试是模拟实际应用的软硬件环境及用户使用过程的系统负荷,逐渐加载或一次性加载、长时间或超大负荷地运行软件,以测试系统的稳定性,并试图找出系统性能瓶颈、异常的地方等。通过负载测试,也可以确定系统的正常工作条件、极限条件等,了解系统可靠性,从而提高软件系统的可靠性、稳定性,减少系统的宕机时间。
性能测试(Performance test),通过测试确定系统运行特性的性能指标数据,如数据吞吐量、响应时间、CPU使用率等。性能测试主要是为了获取或验证事先(如产品规格说明书)已定义的各项性能指标,测试的操作方式和负载测试相近,但结果和目的不一样。
回归测试(regression test),由于软件修改或变更,对修改后的工作版本所有可能影响的范围进行的测试,回归测试的目的是发现原来正常的功能特性出现新的问题——回归缺陷,从而确保原来正常的或符合要求的特性,不受其他区域修改的影响。回归测试,伴随着测试过程,功能测试和系统测试、单元测试和集成测试中,一旦有变更或修正,都要进行相应的回归测试。
1.3 什么是自动化测试
谈到自动化测试,一般就会提到测试工具。许多人觉得使用了一两个测试工具就是实现了测试自动化,这种理解是不对的,至少是片面的。的确,测试工具的使用是自动化测试的一部分工作,但“用测试工具进行测试”不等于“自动化测试”。那什么是“自动化测试”呢?
自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程,即模拟手工测试步骤,通过执行程序语言编制的测试脚本自动地测试软件,自动地完成软件的单元测试、功能测试、负载测试或性能测试等全部工作。自动化测试集中体现在实际测试被自动执行的过程上,也就是由手工逐个地运行测试用例的操作过程被测试工具自动执行的过程所代替。自动化测试,虽然须要借助测试工具,但是仅仅使用测试工具不够,还要包括与之相适应的测试运行机制、流程和其他基础设施的支持。如果仅仅使用工具进行测试,可能只是起辅助测试作用,或者只是完成测试工作的一小部分任务,且这个测试执行过程可能是半自动的,而不是全自动的。
实际上,对于自动化测试有两种说法——“自动化测试”和“测试自动化”。它们之间存在某些微妙的差别,如果严格加以区分,可以看作是两个概念:
概念
自动化测试(Automated Test),侧重说明由测试工具自动地执行某项软件测试任务,自动化处理范围比较小。例如通过某个软件工具完成应用系统的功能测试和性能测试等测试执行工作,而测试的计划、设计和管理等其他工作还是由手工完成的。
测试自动化(Test Automation),侧重说明整个测试过程都由计算机系统自动完成,体现了更理想的自动化思想,有更广的范畴和更大的挑战。它不仅要求由工具完成测试的执行,而且要求测试的设计和管理也能由系统自动完成,例如基于模型实现测试设计的自动化、基于软件设计规格说明书实现测试用例的自动生成、基于数据库系统实现测试管理的自动化等。
根据这样的描述,测试自动化的要求相对来说高得多,即要求所有的测试工作都由计算机系统自动完成,包括:
● 测试环境的搭建和设置,如自动上传软件包到服务器并完成安装;
● 脚本自动生成,如根据UML状态图、时序图等生成可运行的测试脚本;
● 测试数据的自动产生,例如通过SQL语句在数据库中产生大量的数据记录,用于测试;
● 测试操作步骤的自动执行,包括软件系统的模拟操作、测试执行过程的监控;
● 测试结果分析,实际输出和预期输出的自动对比分析;
● 测试流程(工作流)的自动处理,包括测试计划复审和批准、测试任务安排和执行、缺陷生命周期等自动化处理。
● 测试报告自动生成功能等。
这样,测试自动化意味着测试全过程的自动化和测试管理工作的完全自动化,是测试工程师所追求的一种理想境界。如果使整个软件测试过程完全实现自动化,而不需要丝毫的人工参与或干涉,这是不现实的。虽然不能完美地实现测试自动化的这种理想境界,但是,我们可以每时每刻向这个方向努力,不断地问自己——这些测试工作能否由软件系统或工具来自动完成?在测试计划、设计、实施和管理的任何时刻,始终寻求更有效、更可靠的方法和手段,以有助于提高测试的效率。所以,有人更希望将测试自动化解释成“能够使测试过程简单并有效率、使测试过程更快捷而没有延误的方法或努力”。从这里可以认识到,“全过程的自动化测试”思想是非常重要的,会改变我们测试工作的思维,改变我们测试的生活,将测试带到一个新的境界。
在日常工作中,人们并不严格区分“自动化测试”和“测试自动化”这两个概念,而是将它们视为同一个概念。自动化测试是通过工具或程序来对软件进行自动测试,避免大量的手工操作,而只要很少的人工干预或调整。自动化测试是相对手工测试而存在的,所以自动化测试的真正含义可以理解为“一切可以由计算机系统自动完成的测试任务都已经由计算机系统或软件工具、程序来承担并自动执行”。它包含了下列3层含义。
● “一切”,不仅仅指测试执行的工作——对被测试的对象进行验证,还包括测试的其他工作,如缺陷管理、测试管理、环境安装、设置和维护等。
● “可以”,意味着某些工作无法由系统自动完成,如脚本的开发、测试用例的设计,需要创造性,其工作需要手工处理。
● 即使由系统进行自动化测试,还少不了人工干预,包括事先安排自动化测试任务、测试结果分析、调试测试脚本等。
自动化测试,理应从提高工作效率和产品质量的根本目标出发,而不是为了自动化而自动化。在某些时候,如果过分追求测试自动化的完美性,也可能得不偿失,即投入过大,而产出远远小于投入。脱离了自动化测试的根本目标,测试人员可能会变成自动化测试的奴隶。实际上,自动化测试和手工测试往往交织在一起,相互补充,工具执行过程须要人工分析,手工测试时也可以借助工具处理某些数据、日志或显示某些信息。也就是说,不是试图用自动化测试来代替所有的手工测试,而应尊重手工测试,尽量采用自动化测试。
1.4 自动化测试的引入
在进行自动化测试之前,人们往往会有许多疑问,例如,常常会问下列问题。
● 从什么地方开始、从哪里入手?
● 在进行自动化测试前要做哪些准备?
● 测试管理如何适应自动化测试的需求?
● 如何确定自动化测试范围?
● 如何选择测试工具?
● ……
在自动化测试前,确实要做一些准备。如果从个人看,要在技术上做些准备,同时选择合适的测试工具、准备相应的自动化测试支撑环境。而对软件企业来说,需要进行更多的准备,包括思想、流程和人才等多个方面。最重要的是得到软件组织内部管理层的全力支持,对研发流程进行适当的调整,以适应自动化测试所带来的变化。其次,还要对测试人员进行相应的培训,包括编程能力、开发工具使用等方面的培训,以适应测试脚本或工具开发的能力要求。
理想情况下,自动化测试需要相对独立的测试环境。当手工进行测试时,测试环境容易发生变动,这样可能对测试工具的执行带来较大的影响,使自动化测试的执行不够稳定。测试环境的建立,须要考虑硬件和软件,但不同的项目和不同的应用环境差异很大,须要具体问题具体对待。
1.4.1 思想准备
思想决定行为,树立正确的软件测试自动化的观念是非常重要的。例如,思想上高度重视自动化测试的方法,辩证地看待自动化测试和手工测试各自的优势和劣势,而不会认为可以百分之百地实现自动化测试或测试自动化可以完全代替手工测试。如果对自动化测试期望过高,容易急于求成、操之过急,反而不能获得成功。期望越高,失望就越大。
在克服自动化测试所面临的困难上,也要有足够的心理准备。在实施自动化测试过程中,会遇到各种困难,包括技术上的障碍、项目进度的压力和流程上的挑战。例如,Windows应用程序的界面,某些对象不是标准的Windows控件,而是自绘的,就很难被测试工具识别,这种软件的不可测试性,不是由测试人员决定的,而是由开发人员决定的,要解决这类问题,相对困难一些。
测试工具没有智能特性,所以不要寄希望于自动化测试可以发现大量新缺陷。如果想让自动化测试完成所有新功能的测试,是要冒很大风险的。实践证明,自动化测试适合对已有功能的验证,即适合回归测试。如果在思想上期望自动化测试方案解决目前所有遇到的问题,可能会带来更大的问题。例如,测试自动化可以将某些测试流程和管理方法固定下来,融入自动化管理系统中。但是,如果原来就缺乏有效的方法和流程,很难通过自动化测试来从根本上解决这方面的问题。如果寄予不切实际的希望,反而会导致软件产品质量的降低。
总之,正确的思想是辩证地看待自动化测试和手工测试之间关系,将自动化测试和手工测试有机地结合起来,充分发挥各自的优势,从而使测试工作达到最佳平衡。
1.4.2 引入自动化测试的流程
引入自动化测试,除了在思想上有所准备,还要确定哪些项目、项目的哪些测试任务适合实施自动化测试。虽然自动化测试可以无处不在,在不同的测试阶段或不同的测试类型上都能开展自动化测试工作,但是有些测试项目不宜进行大规模的自动化测试,有些测试工作不适合自动化测试,要具体问题具体分析。
不同的测试任务,要选用不同的自动化解决方案。单元测试和开发结合非常密切,其自动化测试一般要建立在集成开发环境之上。功能测试和系统测试有较大的差别,例如功能测试须要关注图形用户界面(Graphical user interface,GUI),GUI又是软件中变化比较大的部分,而性能测试,可以设法避免GUI变化所带来的影响,采用底层通信或应用程序接口(Application Programming Interface,API)等方式来实现和系统的交互作用。所以,针对不同的测试任务,其自动化测试的实施,自然会有不同的考虑。
实施自动化测试,很重要的一点就是选择合适的自动化测试工具。不同的应用环境,要选择不同的测试工具。例如,单元测试工具和编程语言、开发环境有着密切关系,针对.Net或J2EE开发环境,会选择相对应的C#或Java的单元测试工具。不同的测试阶段或不同的测试任务,也会选择不同的工具,如功能测试工具、性能测试工具等。即使对某一特定的测试任务,也有较多的测试工具供选择,这时就要充分地评估测试工具,包括确定工具评估的指标、采取哪些关键业务来检验工具及试用等,从而做出正确的决策。
概括起来,在测试自动化引入的过程中,要遵守一个有效的流程,如图1-8所示,才能达到所期望的目标。
图1-8 选择测试工具的流程
1.4.3 自动化测试范围的考量
自动化测试虽然可以用在任何地方,不论是功能测试、性能测试,还是缺陷管理、测试用例管理和测试环境部署等,都可以采用测试工具或系统来处理。但是,自动化测试有其局限性,有某些特定的适应范围,而不适合其他一些应用场合。这就要求我们好好考量自动化测试的范围。
自动化测试无法处理一些模糊结论的判断和验证,而适合非常明确的任务,以解决某个特定的问题。例如,自动部署某个服务器软件包、软件包中所有文件版本的校验、进行文件中链接检查等,这些任务都很清楚,相应的脚本就比较容易开发,而且将来脚本也容易维护,自动化测试应用起来会一劳永逸。
1. 周期短或一次性的项目
在实施自动化功能测试过程中,往往须要开发大量的测试脚本,而脚本开发的工作量大。如果项目周期很短,可能到项目快结束时脚本还没有完成调试或脚本还不能稳定运行,所以针对周期短的项目,功能测试不宜采用自动化测试方法,而采用手工方法会更好些、成本也会更低。性能测试的自动化测试脚本简单、量也少得多,其脚本开发能很快完成,而且性能测试又很难通过手工完成,所以,对周期短的项目,一般还是借助测试工具来完成性能测试。代码的静态测试和安全性测试,一般也通过工具对代码自动扫描来完成,所以其自动化工作也适合任何类型的项目。
也正是因为自动化测试脚本开发的工作量很大,在一个项目中很难收回脚本开发的投入成本。曾经做过一次测算,功能自动化测试的投入成本,需要在3~4个版本开发之后收回,所以对一次性项目的功能测试,自动化测试解决方案的投入产出率是很低的、不合算。如果是软件产品开发项目,产品的版本会不断升级,其开发过程是长期的任务,会延续几年甚至十几年,所以适合自动化功能测试。
2. 新功能测试和回归测试
工具本身没有想象力和灵活性。根据经验报道,自动测试只能发现30%以下的缺陷,而手工测试可以发现70%以上的缺陷。从这一点延伸出去,我们可以理解,自动化测试工具对新开发的功能进行测试的能力比较弱,不容易发现程序中各种各样的缺陷,改善测试用例的能力也很弱。所以,自动化测试一般不适合新功能的测试,而适合回归测试,胜任对原有功能的验证工作,保证准确、客观地不断重复原有的测试。
3. 自动化测试和手工测试应用范围的对比
在充分利用自动化工具、全力进行自动化测试的同时,牢记不要追求100%的自动化,手工测试仍然至关重要。对高风险的模块或领域要进行更多的人工测试。根据手工测试和自动化测试的各自优势,对人工测试和自动测试区别对待,进行有效分工。根据自动化测试特点及上述分析,相对手工测试,可以确定自动化测试的不同的应用场合,如表1-1所示。概括起来,任务越单调,自动化测试越适合;重复性越大,自动化测试越适合;越容易量化,自动化测试越适合。
表1-1 自动化测试和手工测试的应用场合对比
1.4.4 区别对待不同的测试阶段
单元测试、集成测试、系统测试和验收测试等不同的测试阶段,虽然都可以采用自动化测试来完成,但自动化测试的程度不一样。
● 在单元测试中,自动化测试工具和开发工具集成在一起,自动化测试程度比较高,而且比较全面。如前面所说的,代码的静态扫描,可以充分利用测试工具来完成。而单元的功能测试,一般可以借助单元测试框架实现,但须要写大量的测试脚本或测试代码,手工的工作量不小,这也是许多软件公司的单元测试覆盖率总是不够高的主要原因。
● 在集成测试阶段,自动化测试工具的作用是间接的,不是直接的、主动的。多数测试组织不是通过测试工具验证模块之间的接口,而是通过基本功能的验证来验证系统的集成,即通过BVT来完成每日测试,以满足每日构建、每日集成(持续集成)的需要。
● 在系统测试阶段,人们首先会将自动化测试运用在性能测试、压力测试、可靠性测试中,而在功能测试中,自动化测试的投入会比较谨慎。功能测试中逻辑、数据和API等验证,比较适合自动化测试,而GUI界面、易用性等测试,更宜由手工完成。
● 在用户参与的验收测试中,一般不宜采用自动化测试。同样,针对软件界面操作友好性、易用性的测试,自动化无能为力,必须由手工完成测试。
不同的测试阶段,自动化测试的方法和程度都是不一样的,可以通过表1-2给予总结性的描述。
表1-2 自动化测试在不同测试阶段的应用
1.4.5 如何评估测试工具
满足测试任务及其特点的测试工具可能会比较多,我们须要考虑对它们进行评估,选择出正确的测试工具。如何评估测试工具呢?人们可能会想到下列这些指标:
● 工具的功能是否强大,或者是否满足需求?
● 价格是否合适、在预算之内?
● 性能价格比如何、是否数一数二?
● 工具的质量,工具运行是否稳定?
● 目前的用户量或是否流行?
● 和其他测试工具的兼容性、集成是否容易?
● 技术支持和服务是否及时、方便?
的确,工具的选择要考虑很多的因素,从功能、质量、服务等各个方面找出影响其评估的因素,然后为每个因素设定权重值、打分,最后根据每个工具获得的总分来做出决定。有时候,工具的选择也没有那么复杂,而是根据市场决定,市场哪个流行就选择哪个。市场流行,自然也有其优势,这样做也不无道理。但这样做,具有盲目性,毕竟功能最强的工具不一定适合自己,最合适的工具,才是最好的。
即使排除价格、服务等因素,单就软件功能,考虑具体功能特性也不是一件简单的事情。如以功能测试工具为例,须要考虑下列众多因素。
● 是否简单易用;
● 是否有脚本录制和回放功能;
● 是否具有很强的GUI对象识别能力或提供单独的对象识别、查询功能;
● 是否支持不同的脚本语言(如VB、Javascript、Perl、Python等);
● 脚本语言是否支持数据驱动和关键字驱动的结构;
● 脚本语言是否支持外部函数调用、函数可重用和自身脚本引用等特性;
● 是否支持跨平台,如是否支持Windows/Mac/Solaris/Linux等不同的操作系统;
● 是否支持国际统一编码Unicode(如UTF-8);
● 脚本开发是否具有良好的集成环境(如IDE),包括脚本调试功能;
● 是否支持分布式、远程调用等运行方式;
● 测试结果显示是否直观,如是否具有常用的统计图表、曲线分析手段。
一般来说,测试工具的功能越强,对测试自动化工作越有利,我们会优先考虑。但是,有时须要一分为二地看待问题,功能简单,容易上手;而功能太强,应用起来复杂,培训成本也很高,而且其中一些功能又很少用。例如,脚本语言的功能强大(如类似于C语言的脚本语言),一方面能够为测试人员提供更大的发挥空间、使脚本具有更强的处理能力,另一方面掌握这样的脚本语言要困难得多。
在充分考虑了测试工具的功能特性之外,还要考虑测试工具的成熟性(如版本至少是1.0以上,而不是0.4、0.8等Beta版本)、版本升级是否持续、团队能力、受资助的背景、社区活跃度等因素。
我们建议将开源测试工具作为首选目标。如果开源测试工具应用一段时间之后,确实不能满足自己的需求,可以考虑选择商业化的测试工具。实际上,如果发现工具不能满足自己的需求,因为是开源工具,完全可以对它进行修改(二次开发),增加相应的功能特性,从而满足自己的特定需求,这也是开源测试工具的魅力所在。
千万不要一开始就用巨资引入商业化的测试工具,那样测试人员压力太大,急于求成,反而效果不好,要么测试工具成了摆设,要么从此以后再也不敢提“自动化测试”。
在选择测试工具的过程中,不要过早地下结论。最好对同类工具的几个产品同时进行试用和评估,比较它们的优缺点,最终做出比较明智的、正确的选择。选择开源工具,其中一个关键因素——价格,不须要考虑,无须做性能价格比的分析,更不须要和厂商进行艰难的谈判,省去了不少工作量。当然,我们还须要考虑测试工具的生命力,测试工具的研发由哪家公司或基金会支持、现在是否能得到及时更新和升级等因素。例如,前面介绍的Selenium是由Autoriginate、Contegix、ThoughtWorks等资助的,其中ThoughtWorks是开源世界、软件工程领域(敏捷方法)中大名鼎鼎的公司,而且Selenium的创始人之一——Jason Huggins加入了Google,可能在将来的一天Selenium会得到Google的大力支持,其研发经费就更有保证。开发团队由70多人组成,版本能不断得到升级,工具也逐渐走向成熟,并形成一个较完整的体系,其社区也非常活跃,如图1-9所示。
图1-9 OpenQA社区
我们再看一个例子,Jmeter是由Apache软件基金会(Apache Software Foundation)资助的,而且有很强的开发团队、严格的缺陷管理,版本能得到持续不断的升级,所以我们对JMeter非常有信心。这也就是为什么本书选择Selenium和JMeter作为主要被介绍的测试工具的原因之一。
1.5 如何选择合适的测试工具
在上一节,我们就如何启动自动化测试工作及选择测试工具的总体思路进行了讨论。但测试工具的选择,还须要从某类具体的工具着手,对症下药,才能达到期望的目标。一般来说,测试工具可以分为:
● 单元测试工具,包括静态测试工具和动态测试工具;
● 功能测试工具,包括web功能测试工具、Windows客户端功能测试工具等;
● 性能测试工具,包括负载测试工具、压力测试工具等;
● 测试管理工具,包括缺陷、测试用例和计划等管理工具;
● 其他测试工具,如安全性测试、多媒体测试等。
下面以开源工具为例,分门别类进行讨论。
1.5.1 单元测试工具的选择
出于效率和可行性考虑,单元测试一般由编程人员来完成,测试人员可以辅助开发人员进行单元测试。单元测试和编程保持同步,一边编程、一边测试。例如每完成一个函数的代码,就对这个函数进行测试,用不同的参数来调用这个函数,检查返回值是否正确。只有确认这个函数可以正常工作、没有问题之后,才写下一个函数。所以单元测试的工具应能和开发平台很好地集成起来,用什么编程语言就要选用对应这种编程语言的单元测试工具,例如:
● 如果用Java进行编程,就要选用Java的单元测试工具JUnit(www.junit.org)和TestNG (testng.org),而且JUnit和TestNG可以作为Java集成开发环境(IDE)Eclipse的一个插件,和Eclipse无缝集成,如图1-10所示;
图1-10 测试工具JUnit和开发平台Eclipse的集成
● 如果基于.Net进行软件项目开发,就要选用适合编程语言C#的单元测试工具,如NUnit (www.nunit.org)、NUnitForms*等;
● 如果基于PHP的web应用程序开发,就可以选择PHPUnit作为单元测试工具。
● 如果针对C/C++语言编写的程序,就要选择相应的C/C++单元测试工具CppTest* 、Cgreen*和Check等;
● 如果只是进行纯页面的开发,针对HTML文件的table、form、link等元素进行测试,则单元测试工具选择HtmlUnit*。
这类单元测试工具,须要运行代码、检查运行的状态和结果,一般被称为动态测试工具。
1. xUnit家族
单元测试和开发并行,测试工具应具有良好的扩充性和灵活性。从这个角度看,JUnit树立了榜样,提出了很好的解决方案,构造出先进的单元测试框架。在JUnit影响下,形成了一系列的测试工具,以适应不同编程语言的需求,例如XMLUnit、TagUnit、Jboss JSFUnit、J2MEUnit、DbUnit、SQLUnit和SIPUnit等。
2. Mock Object工具
在单元测试活动中,强调被测试对象的独立性,即软件的被测单元应与程序的其他部分被隔离开来,避免其他单元对该单元的影响。这样,能对单元能进行更为彻底的测试,并能缩小问题分析的范围,容易确定问题出在哪里。这时候,就要设法模拟那些与被测单元相联系的单元,即借助模拟对象(Mock Object)来完成单元的测试。为了达到这个目的,可以选择Mock Object工具来辅助单元测试,如EasyMock、jMock、MockObjects、Xdoclet、MockCreator、MockEJB、ObjcUnit、Mockrunner等。
3. 代码扫描工具
我们知道,代码的质量不仅体现在功能实现上,而且还体现在可维护性上。为了使代码具有良好的可维护性,程序员在编写代码时必须遵守代码规范,包括良好的代码风格、严格的命名、低复杂度等。开发人员是否遵守代码规范,可以通过代码评审来检查,但这样做,其效率比较低、不够完整,所以要借助代码扫描工具来完成。代码扫描工具也有利于开发人员进行自我检查,及时发现问题和解决问题。针对Java的开源代码扫描工具比较多,主要有checkstyle、Findbugs、Jalopy和PMD等。
4. 其他特殊的工具
对于一些复杂的或特定的应用,选择的范围可能会更小些,例如:
● 针对基于AspectJ技术开发的大型Java应用系统应选用Surrogate Test framework单元测试框架;
● 针对基于Struts框架的代码测试,则选用单元测试工具StrutsTestCase;
● 针对Web应用的单元测试,包括验证链接导航、表单输入项和提交、表格内容及其他典型Web应用程序特性的正确性,就可以选择jWebUnit。
1.5.2 功能测试工具
功能测试主要由测试人员完成,而且也是各类测试项目中工作量最大的任务,所以对功能测试工具的选择,我们会更加关注。另外,不同的业务或不同的应用,其软件功能、规模和所采用的技术平台等都差别很大,功能测试工具的选择也更复杂些,须要更深入的分析和评估。这里,我们可以给出比较有效的通用做法,从而能够选择合适的功能测试工具。
1. 系统结构的影响
从被测试软件的系统结构来看,例如:
● 是单机系统还是服务器系统?如果是单机系统,就须要再分析是运行在什么样的操作系统上的;如果是服务器系统,就要进一步分析是什么样的系统架构。
● 如果是服务器系统,被测系统是C/S(Client/Server,客户端/服务器)结构还是B/S (Browser/Server,浏览器/服务器)结构?
● 如果是网络系统,是集中式系统还是分布式系统?
● 如果是通信系统,是同步系统(实时系统)还是异步系统?
对于C/S系统,可以分解为两部分——服务器和客户端。针对服务器的测试,要进一步了解服务器的类型。如果是通用的服务器,如数据库服务器、邮件服务器、FTP服务器,就可以选用相对应的工具进行测试。例如,可以用Spotlight on MySQL(www.quest.com)或mysqlcheck (dev.mysql.com)来检查、分析和优化MySQL数据库的表。
如果是B/S结构,可以看作是浏览器端的测试和Web服务器端的测试。Web服务器端可能包括数据库服务器、应用程序服务器和Web服务器。针对Web服务器的功能测试,可以通过浏览器端的功能测试来完成,可选用的Web测试工具就比较多,包括Selenium、MaxQ(maxq.tigris.org)、Sahi、Canoo WebTest(webtest.canoo.com)、WatiR(wtr.rubyforge.org)、WatiN和WebInject(www.webinject.org)等。
2. 平台的影响
被测应用程序或软件系统基于什么样的平台,如Windows平台还是Linux平台?例如:
● WatiR、WatiN是针对不同的语言(Ruby、C#)实现的Web自动化测试框架;
● 如果是基于Windows平台上的客户端,可以选用AutoIT或AutoHotKey;
● 如果是Linux的Java客户端,可以选Abbot或Squish。
其中Squish(www.froglogic.com)是跨平台(Windows/Linux/Mac)的、专业性的功能测试工具,支持Java SWT/RCP和AWT/Swing (富客户端)应用、Web 2.0/Ajax应用、Mac OS X Carbon/Cocoa应用和其他类型的应用。
3. 测试的机制
多数功能测试工具都是从GUI对象识别入手,模拟鼠标和键盘的操作和验证界面元素的实际显示结果来完成测试,例如Selenium。如果不须要关注界面的验证,而是进行功能逻辑的验证,这时可以选择像MaxQ、TestMaker(http://www.pushtotest.com/products/testmaker)等这样的测试工具,不直接录制Web的界面,避免在回放时不能识别控件而造成回放停止,而是采用Web Proxy代理方式,获得浏览器提交的请求数据包,直接转发给服务器,这样测试速度快而且稳定,如图1-11所示。
图1-11 MaxQ运行机制示意图
举一个例子,如果我们须要快速编码来测试Web service,就可以选择WebInject或MaxQ,每个测试用例使用XML标签来描述,也许我们能在一个下午的时间里就执行完自动化测试。如果需要高端的工具以构建强大的测试,包括用到一些其他的系统资源(如文件系统、数据库、e-mail等),那么就最好选择Selenium、TestMaker等工具。介于这两者之间,不简单也不难,可以选择soapUI或WatiR/WatiN,而且这些工具也可以根据需要扩充,如soapUI可以使用Groovy脚本。
1.5.3 性能测试工具
当我们谈到开源软件阵营中的负载测试或性能测试工具时,首先会想到的是Apache JMeter (http://jakarta.apache.org/jmeter/index.html),它最初是为了Web应用而开发的性能测试工具,但现在已扩展到其他应用领域,如数据库、邮件服务器、SOAP或LDAP服务器等。JMeter可以针对许多不同的静态资源和动态资源(Servlets、Perl脚本、Java对象、数据查询和FTP服务等)进行负载测试或性能测试,也可以进行非用户界面(non-UI)的功能测试。JMeter作为开源性能工具的代表,是本书重点介绍的工具,详见第5章。
选择性能测试工具时,主要考虑是否支持多种通信协议或服务器类型、是否支持不同的负载模式、是否有良好的系统资源监控机制和报表生成机制等。下面这些开源工具,可供选择。
● Grinder是一个很好的负载测试框架,被誉为J2EE上的LoadRunner。通过Jython来编写测试脚本,支持多种协议(如HTTP、SOAP和REST等 )的Web服务和应用服务器(如CORBA、RMI、JMS和EJBs等),基于HTTP的测试可以由浏览器来记录整个要测试的过程。与此相关的工具,还包括Eclipse的Grinder插件GrinderStone (http://code.google.com/p/grinderstone/)、分析器Grinder Analyzer、源于Grinder的持续性能测试工具webFlange等。
● TestMaker通过基于Jython的测试代理(test agents)来完成测试,并借助PTTMonitor以监控应用服务器的资源和统计信息(如线程、对象和调用等)。其开放版本是商用软件的“简装版本”,不支持分布式的负载部署(即模拟的并发用户数量受到限制),其他功能比较全面。
● OpenSTA (www.opensta.org)是针对B/S结构的性能测试开源工具,基于公共对象请求代理体系结构(Common Object Request Broker Architecture,CORBA),并通过虚拟代理(proxy)来记录通过proxy的HTTP请求,而其性能指标收集器收集各项性能指标,然后进行分析,能提供较为丰富的图形化测试结果,提高了测试报告的可读性。
● Siege(http://www.joedog.org/JoeDog/Siege)是一个开源的Web压力测试和评测工具。
● ApacheBench(apache服务器ab命令,httpd.apache.org)能同时模拟多个并发请求,专门用于Web服务器的基准测试。
● DBMonster是一个生成随机数据、用来测试SQL数据库的压力测试工具。
● JDBHammer是针对MySQL数据库服务器进行压力测试的开源工具,而MySQL官方提供的压力测试工具则是mysqlslap。
另外要说明的是,TestMaker是一个更灵活的框架,可以和Selenium、soapUI集成,充分利用Selenium和soapUI的测试能力,而TestMaker只是更好地调度、监控和管理测试的过程,监控系统的性能指标,获得测试结果,如图1-12所示。
图1-12 TestMaker和Selenium集成进行压力测试
1.5.4 测试管理工具
软件测试离不开管理,包括测试计划、测试用例、测试结果和缺陷等管理,这些管理也通过工具和系统来帮助处理,以提高管理的效率和准确性。测试管理工具的选择,依赖于测试组织的规模和流程。规模小的组织,可以选轻量型的测试管理工具;而规模大的组织,应选择功能强、支持多项目和分布式处理的测试管理工具。
对于轻型的开源测试管理框架,可以选用JtestCase、FitNesse、Salome TMF、JTR(Java Test Runner)等。例如,可以选用FitNesse,它能够帮助客户、测试人员和开发人员加强软件开发过程中的协作,通过在web页面上简单的输出和预计输出的表格就可定义验收测试、管理测试用例等。
对于更为规范的、具有一定规模的软件组织,可以选用TestLink、Bromine、Eclipse TPTP等测试管理框架或系统。
● Bromine(http://bromine.seleniumhq.org)集成了Selenium,可以轻松地跟踪和管理测试项目、需求、测试计划、测试用例和缺陷,也可以远程调试和执行测试脚本,如图1-13所示;
图1-13 Bromine测试结果管理界面
● Eclipse TPTP(Test & Performance Tools Platform)可以为软件包独立测试和性能测试提供全方位服务,覆盖整个单元测试过程;
● TestLink管理测试项目、需求、计划、用例及其执行等,将在第9章详细介绍。
软件测试管理的重要工作之一是缺陷管理,缺陷管理工具有Mantis、Bugzilla、Bugfree、Scarab、TrackIT、Itracker等,第8章将详细介绍Mantis。
1.5.5 其他测试工具
除了常用的单元测试、功能测试、性能测试和测试管理工具之外,我们还要选择其他测试工具,服务于安全性测试、多媒体(如IP电话通信)测试、测试过程监控等自动化工作。
1. 安全性测试工具
主要有Nikto、Paros proxy、SPI Dynamics WebInspect、Tripwire、TamperIE、Wapiti,其中前3项工具的功能强大,而其他工具则检查某个方面的测试。例如,TamperIE是一个小巧的XSS漏洞检测辅助工具,WebScarab分析HTTP和HTTPS协议的通信。除此之外,还有专门检查数据库SQL注入攻击漏洞的工具,如sqlninja。
Paros proxy是基于Java的web代理程序,可以评估Web应用程序的漏洞。它支持动态地编辑、查看HTTP/HTTPS,从而改变cookies和表单字段等项目。它包括一个Web通信记录程序、Web圈套程序(spider)、散列(hash )计算器,还有一个可以测试常见的Web应用程序攻击(如SQL注入式攻击和跨站脚本攻击)的扫描器。
2. 可达性测试工具
可达性(Accessibility)在国际性软件测试中也是不可忽视的。这类工具包括色彩对比度分析、键盘和鼠标的特殊操作等。微软公司在2009年3月发布了两种可达性测试工具(http://www.codeplex.com)。
● AccChecker:用户界面可达性检查工具(UI Accessibility Checker) ;
● UIA Verify :用户界面自动验证(UI Automation Verify)。
除此之外,还有很多这类测试工具,详见:http://www.w3.org/WAI/ER/tools/complete。
3. 多媒体测试工具
多媒体应用越来越多,对测试工具的要求也越来越高,须要覆盖语音(VoIP)、视频(Vedio)和IP电话等各项多媒体应用的特殊测试,如多媒体数据交换、服务质量(QoS)等。多媒体方面的开源测试工具有Ethereal、AuthTool、SIPp、 Seagull、Sofia、Asterisk和X-Lite等。
4. 网络监控工具
网络监控工具也常常在测试中使用,这类开源工具比较多,选择的余地很大,常用的工具有Nessus、Ethereal/Wireshark、Snort、Switzerland和Netcat,其中Wireshark就很不错。
1.6 小结
人们对软件测试自动化越来越感兴趣,总是寻求各种机会使用不同的测试工具。测试工具固然是自动化测试的一种最直接的体现,或者说,是通向自动化测试必经之路,但自动化测试具有更丰富的内涵,而且我们也须要在真正理解自动化测试内涵,这样才能将自动化测试工作做得更好。
对于自动化测试,不仅要理解其含义,而且要认识到它的优势和劣势,例如,自动化测试可以帮助我们提高测试效率、缩短测试周期,使测试结果更可靠、准确,而且能提高测试团队的士气。同时,测试自动化也有不利的一面,即在创造性、发现新缺陷等方面能力不足。所以,要辩证地看待自动化测试和手工测试,在工作中,将两者有机地结合起来,充分发挥各自的优势。
在准备自动化测试时,首先要有一个正确的认识,如辩证地看待自动化测试和手工测试之间关系,确定哪些任务和范围适合自动化测试;然后,根据项目及其业务的特点,了解不同类型的自动化测试工具,选择合适的自动化测试工具,包括经过比较分析、试用和评估等一系列环节,最终确定测试任务所需要的测试工具。