序言:自动化测试中,自动化
测试用例是一个重点中的重点,个人以为,到底如何去定位自动化测试
用例设计的 形式和发展是决定自动化测试成败的关键,根据一些研究和看法,我写了一个自动化测试用例设计的一个大概情况,当然一家之言而言,当然,大家在测试过程中, 接触过自动化测试的,肯定就接触过自动化测试用例,其是
自动化测试脚本本身也是一种自动化测试用例,看看以下的情况大家遇到过么,希望大家有什么想法,提 出来吧。
一、自动化测试用例应用
手工测试用例是针对手工测试人员,自动化测试用 例是针对自动化测试框架,前者是手工测试用例人员应用手工方式进行用例解析,后者是应用脚本技术进行用例解析,两者最大的各自特点在于,前者具有较好的异 常处理能力,而且能够基于测试用例,制造各种不同的逻辑判断,而且人工测试步步跟踪,能够细致的定位问题。而后者是完全按照测试用例的方式测试,而且异常 处理能力不强,往往一个自动化测试用例运行完毕后,报一堆错误,对于测试人员来定位错误是一个难点,这样往往发现的问题很少。所以,根据其各自的特点,需 要将两者有很好的定位:手工测试是在软件版本前几轮测试的重点,目的是验证功能,发现问题;自动化测试是应用在后几轮版本,保证软件版本模块修改或者添加 新功能后,没有影响开始的功能模块(因为软件中,各模块之间的接口以及类、函数方法等的互相引用,也是容易出问题的地方)。
二、自动化测试用例设计发展
1、自动化测试用例设计发展前期
记得,当时的自动化测试开展是针对测试设备设计一套测试环境系统,用于自动化例行测试,根据此,专门撰写了一套自动化测试用例,并转化成自动化测试脚本。之后整套系统都失败了,失败原因包括:
a、系统太过于庞大,测试用例也过于繁琐,每次测试运行下来,测试结果都夹杂着一大堆各种错误,有可能是产品问题,有可能是脚本问题,也有可能是用例问 题,这样下来,测试人员每次运行一遍都要面对大量的问题,维护的几次就放弃了,问题越来越多,根本没办法去定位,这样反而浪费了大量的成本和时间。
b、搭建的一套测试环境系统,各个产品功能模块都互相联系在一起,都互相有影响,容易造成问题。
c、更重要的是,由于是单独搭建的一套测试环境系统,其自动化测试用例与手工测试用例没有太大关系,这样就造成了其自动化测试很难对手工测试进行辅助。
2、自动化测试用例设计发展前中期
这时,自动化测试用例来源于手工测试用例,首先,自动化测试根据手工测试用例进行转换而来(举个例子:CLI测试时,自动化测试用例是根据手工测试用例 的步骤,将其需要输入的CLI命令和回显进行填写),之后,自动化测试脚本人员根据其自动化测试翻译为脚本。这样做的好处就是手工测试用例与自动化测试用 例的结合,保证了自动化测试的明确性,后期的改进还包括
a、将自动化测试用例根据手工测试用例进行了分层,把一些共性功能和全局变量抽象到了更上一层,保证复用性和降低维护性。
b、设计的自动化测试框架的管理。
经过一段时间之后,问题还是很大,主要问题在于
1)前期为了追求自动化测试覆盖率,往往忽视了自动化测试用例的质量,大家想想,出产一个自动化测试项目,得经过手工测试用例—自动化测试用例—自动化 测试脚本三个阶段,而自动化测试用例是手工测试人员来撰写,因为其懂业务;自动化测试脚本是由专门的自动化测试人员撰写,但是这导致了一个项目出产的周期 长(需要经过两个阶段,而且还要反复调试),而且由于经过了两个阶段,所以伴随问题也多了,特别是接口这方面,往往由于两者的沟通和认知问题,使得自动化 测试项目的发布后还隐藏大量问题,往往使测试人员疲于调试和维护。
2)虽
然是按照手工测试用例设计出来的,但是由于手工测试用例开始没有考虑到自动化测试者一块,因此手工测试用例的每个测试模块往往测试步骤很 长,而且测试前后不能保证测试环境的恢复,所以也造成了后期一个自动化测试项目的问题以及出产成本。(这里建议最好自动化测试用例的每个功能模块的步骤不 长,而且每个模块之间不要有联系,这样是要从手工测试入手的)
3、自动化测试用例设计发展中期
在这个过程中,最好的是测试人员能够根据自动化测试框架与平台来自行进行测试脚本的设计,往往在前几轮的测试中,手工测试人员就能在手工测试的同时将自动化测试脚本设计了出来
a、录制就是这样一种思想,测试人员在测试过程中,本身就是在测试过程中,将测试人员的测试过程进行了记录,所以,我的想法一直是,录制的方向是没错的。
b、而针对CLI测试,也可以制作了这么一个录制工具,就是模拟制作一个超级终端,测试人员应用其进行手工测试,其工具自动记录其命令行操作, 而且手工测试人员能进行回显的需要匹配的某一个字段进行选择,然后在后台根据模板,自动生成一个自动化脚本,之后测试人员自行进行维护即可,这样可以缩减 环节,降低出错几率和维护问题。
c、当然,要做到这一步,一个强大的自动化测试框架和平台是其支撑,我曾经做过一个基于GUI的自动化测试框架,部门里面也动员过一次试用,每 个产品线都出了一两个人进行脚本开发,测试人员往往对脚本开发没什么太大兴致,更多的是一种好奇,而且调试工作大多是我做的,整整10多个产品线,调试了 我大部分时间,因此其难点本身不是在于脚本的开发,因为当时测试人员开发出这些脚本是很快的事情,其真正难点在其测试人员的调试和维护方面,而且测试人员 往往疲于去进行这方面,他们在乎的是测试和业务本身,要协调这方面的冲突是一件很难的事情,需要不断思考和总结吧。
4、自动化测试用例设计发展中后期
留一个中后期,现在的自动化测试用例设计发展还是很浅,还需要一个长远的发展过程,中后期发展成什么形式,因为见识有限,所以请大家积极猜想啦。希望能给我带来一些见识和想法。
三、一些感想
下面感想仅我个人之言:自动化测试就本身而言,其实技术方面的前瞻性是需要的,但是自动化测试确实是一个长期的过程,对自动化测试的定位很重 要,然后是一系列的细节问题,每一个问题都是需要值得重视的问题;定位、细节、技术真的都是缺一不可啊,而且还要把握这么一个平衡,想到自己以前注重需 求,后到注重技术,后又因为技术怀疑需求,最后又回归到认识需求,短短时间,总有变化,现在想想,三者,技术是基础,需要不断学习,但却不能看的太远而忽 略了现在的最重要的需求,在实现现在需求的同时,不断步步跟进,进行探索。自动化测试还真是一个“步步惊心”的过程啊。
版权声明:本文出自 散步的SUN 的51Testing软件测试博客:http://www.51testing.com/?382641
eclipse中配置SVN
eclipse中配置SVN 1.先安装一个Subclipse,地址:http://subclipse.tigris.org/ 2.可以通过Eclipse的Update Site安装方式:http://subclipse.tigris.org/update_1.4.x或者下载下来之后,解压缩复制到Eclipse目 录即可。
3.启动程序后在Eclipse配置项的Team里面就会多出SVN,就可以进行配置了。
第一步:eclipse->window->open Perspective->other
弹出一个对话框,选中svn,OK http://www.svn8.com
第二步:配置svn资源
新建一个svn资源库,finish
第三步:检出项目http://www.svn8.com
4.想要提交一个项目,对项目点击右键Team——Share project就可以将项目导入SVN了
ECLIPSE中SVN客户端(subclipse)的安装和配置
2009-04-16 06:35
subclipse是Eclipse的SVN插件,通过subclipse在Eclipse中就对SVN进行管理(提交、更新、合并、切换分支等等)。这篇文章介绍的就是如何安装和配置subclipse。
安装 访问网页
http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 选择你对应的Eclipse的插件下载地址(Eclipse update site URL)。之后就是简单地调用Eclipose的插件安装程序了。
配置SVN库
插件安装完成以后,重启Eclipse,选择Open SVN Perspective
在SVN Perspective中你就可以配置需要使用的SVN资源库了。
SVN资源添加完毕以后,你就可以通过Eclipse浏览资源库了。
建立工程 通过选择你想Checkout的SVN路径点击右键,在弹出的菜单中选择“Checkout”检出,依据Eclipse的提示你就可以将Checkout的内容作为Eclipse的项目了。
恭喜大家通过以上步骤完成了Eclipse中SVN插件(subclipse)的安装以及通过subclipse 建立了Eclipse项目
,下面这个步骤是在Eclipse中设置subclipse相关的快捷方式以提高大家使用subclipse的效率。
快捷方式设置 在Eclipse中可以对常用的subclipse功能设置快捷方式以提高大家的工作效率。点击Eclipse->Windows->Preferences->Gerneral->Keys,大家看到如下一个页面。
在这个窗口中对Category进行排序,找到SVN对用的功能项(提交、更新等功能一应俱全)。选中你想要设置快捷方式的功能项,并在对应的Binding输入框中键入你想要的快捷方式,以上图为例,我将更新功能的快捷方式设置成了Alt+U
总结 以上就ECLIPSE中SVN客户端(subclipse)的安装和配置的全过程了,祝看到本文的同学操作顺利。
并发性能测试的种类与指标
并发性能测试的种类取决于并发性能测试工具监控的对象,以QALoad自动化负载测试工具为例。软 件针对各种测试目标提供了DB2、DCOM、ODBC、ORACLE、NETLoad、Corba、QARun、SAP、SQLServer、 Sybase、Telnet、TUXEDO、UNIFACE、WinSock、WWW、Java scrīpt等不同的监控对象,支持Windows和UNIX测试环境。
最关键的仍然是测试过程中对监控对象的灵活应用,例如目前三层结构的运行模式广泛使用,对中间件的并发性能测试作为问题被提到议事日程上来,许多系统都采用了国产中间件,选择Java scrīpt监控对象,手工编写脚本,可以达到测试目的。
采用自动化负载测试工具执行的并发性能测试,基本遵循的测试过程有:测试需求与测试内容,测试案例制定,测试环境准备,测试脚本录制、编写与调试,脚本分配、回放配置与加载策略,测试执行跟踪,结果分析与定位问题所在,测试报告与测试评估。
并发性能测试监控的对象不同,测试的主要指标也不相同,主要的测试指标包括交易处理性能指标和 UNIX资源监控。其中,交易处理性能指标包括交易结果、每分钟交易数、交易响应时间(Min:最小服务器响应时间;Mean:平均服务器响应时 间;Max:最大服务器响应时间;StdDev:事务处理服务器响应的偏差,值越大,偏差越大;Median:中值响应时间;90%:90%事务处理的服 务器响应时间)、虚拟并发用户数。
性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测 试。负载测试和压力测试都属于性能测试,两者可以结合进行。通过负载测试,确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指 标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。
一、概述
性能测试在软件的质量保证中起着重要的作用,它包括的测试内容丰富多样。中国软件评测中心将性能测 试概括为三个方面:应用在客户端性能的测试、应用在网络上性能的测试和应用在服务器端性能的测试。通常情况下,三方面有效、合理的结合,可以达到对系统性 能全面的分析和瓶颈的预测。
·应用在客户端性能的测试
应用在客户端性能测试的目的是考察客户端应用的性能,测试的入口是客户端。它主要包括并发性能测试、疲劳强度测试、大数据量测试和速度测试等,其中并发性能测试是重点。
并发性能测试是重点
并发性能测试的过程是一个负载测试和压力测试的过程,即逐渐增加负载,直到系统的瓶颈或者不能接收 的性能点,通过综合分析交易执行指标和资源监控指标来确定系统并发性能的过程。负载测试(Load Testing)是确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统组成部分的相应输出项,例如通过量、响应时间、CPU负载、内存使 用等来决定系统的性能。负载测试是一个分析软件应用程序和支撑架构、模拟真实环境的使用,从而来确定能够接收的性能过程。压力测试(Stress Testing)是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。
并发性能测试的目的主要体现在三个方面:以真实的业务为依据,选择有代表性的、关键的业务操作设计 测试案例,以评价系统的当前性能;当扩展应用程序的功能或者新的应用程序将要被部署时,负载测试会帮助确定系统是否还能够处理期望的用户负载,以预测系统 的未来性能;通过模拟成百上千个用户,重复执行和运行测试,可以确认性能瓶颈并优化和调整应用,目的在于寻找到瓶颈问题。
当一家企业自己组织力量或委托软件公司代为开发一套应用系统的时候,尤其是以后在生产环境中实际使 用起来,用户往往会产生疑问,这套系统能不能承受大量的并发用户同时访问? 这类问题最常见于采用联机事务处理(OLTP)方式数据库应用、Web浏览和视频点播等系统。这种问题的解决要借助于科学的软件测试手段和先进的测试工 具。
举例说明:电信计费软件
众所周知,每月20日左右是市话交费的高峰期,全市几千个收费网点同时启动。收费过程一般分为两 步,首先要根据用户提出的电话号码来查询出其当月产生费用,然后收取现金并将此用户修改为已交费状态。一个用户看起来简单的两个步骤,但当成百上千的终 端,同时执行这样的操作时,情况就大不一样了,如此众多的交易同时发生,对应用程序本身、操作系统、中心数据库服务器、中间件服务器、网络设备的承受力都 是一个严峻的考验。决策者不可能在发生问题后才考虑系统的承受力, 预见软件的并发承受力, 这是在软件测试阶段就应该解决的问题。
目前,大多数公司企业需要支持成百上千名用户,各类应用环境以及由不同供应商提供的元件组装起来的复杂产品,难以预知的用户负载和愈来愈复杂的应用程序,使公司担忧会发生投放性能差、用户遭受反应慢、系统失灵等问题。其结果就是导致公司收益的损失。
如何模拟实际情况呢? 找若干台电脑和同样数目的操作人员在同一时刻进行操作,然后拿秒表记录下反应时间?这样的手工作坊式的测试方法不切实际,且无法捕捉程序内部变化情况,这样就需要压力测试工具的辅助。
测试的基本策略是自动负载测试,通过在一台或几台PC机上模拟成百或上千的虚拟用户同时执行业务的 情景,对应用程序进行测试,同时记录下每一事务处理的时间、中间件服务器峰值数据、数据库状态等。通过可重复的、真实的测试能够彻底地度量应用的可扩展性 和性能,确定问题所在以及优化系统性能。预先知道了系统的承受力,就为最终用户规划整个运行环境的配置提供了有力的依据。
并发性能测试前的准备工作
测试环境:配置测试环境是测试实施的一个重要阶段,测试环境的适合与否会严重影响测试结果的真实性 和正确性。测试环境包括硬件环境和软件环境,硬件环境指测试必需的服务器、客户端、网络连接设备以及打印机/扫描仪等辅助硬件设备所构成的环境;软件环境 指被测软件运行时的操作系统、数据库及其他应用软件构成的环境。
一个充分准备好的测试环境有三个优点:一个稳定、可重复的测试环境,能够保证测试结果的正确;保证达到测试执行的技术需求;保证得到正确的、可重复的以及易理解的测试结果。
测试工具:并发性能测试是在客户端执行的黑盒测试,一般不采用手工方式,而是利用工具采用自动化方 式进行。目前,成熟的并发性能测试工具有很多,选择的依据主要是测试需求和性能价格比。着名的并发性能测试工具有QALoad、LoadRunner、 Benchmark Factory和Webstress等。这些测试工具都是自动化负载测试工具,通过可重复的、真实的测试,能够彻底地度量应用的可扩展性和性能,可以在整 个开发生命周期、跨越多种平台、自动执行测试任务,可以模拟成百上千的用户并发执行关键业务而完成对应用程序的测试。
测试数据:在初始的测试环境中需要输入一些适当的测试数据,目的是识别数据状态并且验证用于测试的 测试案例,在正式的测试开始以前对测试案例进行调试,将正式测试开始时的错误降到最低。在测试进行到关键过程环节时,非常有必要进行数据状态的备份。制造 初始数据意味着将合适的数据存储下来,需要的时候恢复它,初始数据提供了一个基线用来评估测试执行的结果。
在测试正式执行时,还需要准备业务测试数据,比如测试并发查询业务,那么要求对应的数据库和表中有相当的数据量以及数据的种类应能覆盖全部业务。
模拟真实环境测试,有些软件,特别是面向大众的商品化软件,在测试时常常需要考察在真实环境中的表现。如测试杀毒软件的扫描速度时,硬盘上布置的不同类型文件的比例要尽量接近真实环境,这样测试出来的数据才有实际意义。
并发性能测试的种类与指标
并发性能测试的种类取决于并发性能测试工具监控的对象,以QALoad自动化负载测试工具为例。软 件针对各种测试目标提供了DB2、DCOM、ODBC、ORACLE、NETLoad、Corba、QARun、SAP、SQLServer、 Sybase、Telnet、TUXEDO、UNIFACE、WinSock、WWW、Java scrīpt等不同的监控对象,支持Windows和UNIX测试环境。
最关键的仍然是测试过程中对监控对象的灵活应用,例如目前三层结构的运行模式广泛使用,对中间件的并发性能测试作为问题被提到议事日程上来,许多系统都采用了国产中间件,选择Java scrīpt监控对象,手工编写脚本,可以达到测试目的。
最近和几个同事一起组织了一门ETP(Engineer Training Program)的课程,叫做Advanced Performance
Testing。叫Advanced不是因为多么高深,而是因为这是一个多次的系列课程,而且里面结合了大量的实例和实践的经验,不希望只是泛泛的介绍。当然,这样叫还是会觉得有些大言不惭的,毕竟做
性能测试久了,知道深浅。
最近在Weinberg(对,还是他,可见我读书多么慢)的《becoming a technical leader》书中看到一段话,提到他对于培训的一点心得,他对于成功与否的判断标准是受众在其后对于这个领域的关注度是提高了还是下降了。我也希望在我 们这个系列的课程结束之后,大家对于这一块有了更多的认识和了解,也愿意去更深入的学习和实践。总之,希望会有一些帮助。
昨晚上完第一次overview的课后坐地铁回家,碰到一位来上课的同事,他对于我在课上提到的和性能测试相关的几个观念有一些印象。看来,简洁的归纳 是有助于传播的,可能比一堆的checklist更容易让人记住和获取一些新的想法。这里也整理一下发出来供大家参考。
1. 精确和模糊
这是困扰很多性能测试人员的一个问题。因为基本上性能测试都需要得到一个精确的量化的结果,比如:
a. 系统可以支持10,000个并发连接
b. 每秒钟可以处理80封电子邮件
c. 可以支持3000人同时浏览网页
......
类似的数据可能出现在需求中,也可能出现在测试的结果里面。使得我们认为,相比功能测试或者稳定性测试而言,性能测试是一种要求精确的测试。
但是,真的是这样吗? 试着回答下面这个问题:
一辆汽车开100公里需要多少汽油?
直觉上你会说不同的车不一样,对,这是好的开始,那好,就确定是某一台确定的车,不仅是型号,就是门口的某一台。
嗯,怎么样?开始犯难了吧,特别是如果你是一个严谨的人。因为你的大脑开始快速列出下列条件:
1. 坐几个人,带多重的物品?
2. 路况如何,是高速还是拥挤的市区?
3. 天气如何,温度如何,要开空调吗?
4. 驾驶习惯是怎样的?
......
还有很多,越有经验的人可以列出越多,想想F1调整一下尾翼的角度就可以改变下压力之类的事情。天哪,我要开一个长长的清单。
到现在,你还觉得性能测试是一个精确的测试吗?也许问题出在有太多的前置条件,它们或大或小的影响着测试的结果。
所以呢,我们应该怎么办?这是对很多新参与性能测试的人来说最难的问题,而不是那些看起来复杂的工具。大家常会问:我怎么知道该用什么样的sample?
关于这些前置条件,或者我们称之为假设(assumption),我把一些做法归为三个阶段。
Stage 1:做了假设却不知道自己做了假设
比如前面提到的那个油耗的问题,有人的做法是我就开100公里看看,得出来是多少就是多少,比如9L。然后我就告诉别人这个车的100公里油耗就是9L。
问题是这样的结果对你是OK,因为你有切身的体验,知道遇到的状况,可是测试的报告是要给别人,甚至你都无法直接面对或者沟通的人参考。这就会很容易误 导别人,即便这不是你的本意,而且你自己也确定你是真实的记录了结果。这里的问题在于你并不清楚自己所做的假设,因为我们一直在做这样的假设。
Stage 2:做了过多的假设
“当路面平坦,无任何红绿灯,风速5km/h, 只有一名70kg的乘客,时速稳定在70km/h, 良好驾驶习惯,... ,的情况下, 油耗是7.1 L/100 km.”
这样可能很严谨,但是对你的报告的读者而言,这样的数据有多大意义,因为他们没有你那么幸运,有这么良好的环境。
Stage 3:做必要和合理的假设。
生活有时候是需要一些妥协和折衷,如果这些折衷是必要的和合理的。因为跳出来看,我们的测试需要提供有价值的信息,所以为了这样有价值的信息,做出必要的和合理的假设是可以接受的。
好吧,也许这不是你想要的答案,但它是我目前给自己的解释,和安慰。
2. 宏观和微观
这也是一个有趣的对立。在做性能测试,特别是整个产品的性能测试的时候,我们看到的是产品的核心功 能和主要的大的功能模块,比如数据库、web服务器、核心的daemon等等。在脑海里,我们有一个架构图,哪怕你没有把它画出来。所以有时候,我们会 想,性能测试对于产品的视角是宏观的,看大的组件,而不是具体的细节的东西。
果真是如此吗?看看下面的例子:
1. 把daemon的log级别改为debug (log_level从2改到5)之后,性能下降了差不多一半。
2. 关掉一个cache选项
3. 打开keepalive选项
4. 打开DNS反向查询
......
上面都是些细枝末节的设置,一个配置项而已,藏在DB的某张表或者某个ini里面。但是改变之后,得到的性能结果可能大不相同。这些都是我曾遇到过的例子,也是让我改变看法的一些经历。
Scott Barber(本人非常尊敬的性能测试方面的专家)在他的一篇文章里讨论了这个话题。
“Macro- and Micro-tests, macro strategies and micro-plans, macro-level application usage and micro-level usage implementation details, macro-level result summaries for executives and micro-level test results for developers... it sounds like a day in the life of a performance tester to me.”
摘自他为Software Test & Performance杂志写的一个系列文章,叫做Peak Performance,其中的2006年9月的一期,文章名是 Macro to Micro And Back Again
Macro to Micro And Back Again,嗯,很好的诠释。
亚里士多德说世上的道理不是被讲一遍两遍而是成千上万遍,是的,因为Weinberg也讲了一遍,就在上面提到的那本书里面。请原谅我再次引用他的话,粉丝嘛。
“Although it's necessary to have an overview of the problem, the big picture often turns on one critical detail.”
critical detail, 对,就是这个term。其实不光是这里说的测试,工作和生活中的很多事情都是一样,不是要不要关心细节,而是它是否critical。
那么,怎么区分一个细节是不是critical或者怎样找到critical的detail呢?
嗯...,这是个好问题,不过不好意思这个不是这里要讨论的范畴。
3. 项目和任务
性能测试本身肯定是一个任务,无论对于被安排去做这个的人,或者安排的人。但是它有时候也像一个项目,对于去做这件事情的人。为什么呢?
首先你需要和很多的人打交道。
产品经理或者客户:获取需求,设定目标。
QA manager/lead:讨论resource和schedule。包括需要的机器,环境,软件,还有整个计划。
开发人员:查找问题和调优等。
功能测试的owner: 性能测试人员可能不是什么功能都很懂。
Admin:Lab,网络,DB等等
其次,它是一个周期很长,跨度很大的工作。特别是对于一个比较大的产品而言。你需要准备详细的测试设计,包括目标、范围、可能的方法,以及上面 提到的资源和时间计划;然后邀请很多人来评审这个计划;接下来要准备工具、环境和测试数据。然后是执行,记录分析结果。如果有问题还要反复的调整和 regression。最后要整理报告,回答疑问。
说它是一个项目一来是因为上面的原因导致工作的复杂性,还有一些原因是因为性能测试带有评测的性质,因为你是在试图去度量、衡量或者评价一个东 西,而且带有比较绝对的结果。这样导致性能测试不可避免的要引入一些权威性的问题,尽管你并不一定期望这样。这使得很多的东西就像一个其他项目一样,有期 望管理和良好的外部沟通和协调的需要。所以有时候,更愿意把它作为一个小的项目来看待,这样或许可以做得更全面。
许久以前就答应悟石要分享一下我眼中的
性能测试工程师,结果托来托去快托过年了,囧…
想想来杭州有半年了,也对目前主站的性能评测团队工作模式有些许了解了,再加上以前在上家雇主也做过几年自认还算很有技术含量的性能测试工作,我想我还算有点资格说的吧:)
性能测试说的装B点儿,其实没啥,就是和Response Time(或者说latency)、throughput(也可以说capacity)以及scalability打交道。弄懂了这三个要素,应该就算是一个合格的性能测试工程师了。
当然,我不会装B,只是一介武夫,所以我接下来只想从偏技术层面聊聊我心目中真正的主站性能测试工程师是啥样的:
1、大局观。性能测试工程师一定要有系统化的思维,要站在整个系统测试的 角度看问题。一个优秀的性能工程师必须要有相当的知识广度。否则在测试期间,你必须依赖外界援助(比如DBA,Dev或OPS)来协助,效率不高,更关键 的是可能会被误导,漏掉很多性能BUG。我常常看到组里的童鞋们在压测时一看到TPS降了,就死盯着应用,就着急的去分析线程或做CPU Profiling。找不到原因后有时问到我时,我习惯的第一句总是 你看过DB么?确认DB端正常么?看过压测客户端么?确认压测端正常么? 我个人意见:不要老凭经验,一有重复症状就思维定式;一定要坚持先从全局看问题,隔离到是应用层面、DB层面抑或是压测客户端层面后再进一步深入定位问 题。
2、技能深度。在性能测试工具方面有自己独特的理解;同时也应该在操作系统、数据库、应用程序等方向的配置管理与调优方向上非常的熟悉。
3、敏感。这个一方面是天赋,一方面是经验积累吧, 很多隐蔽的性能问题确实是需要丰富的经验才能发现,极容易漏掉:)
4、兴趣。其实这条才是最重要的^-^
如果说具体些通俗些,我眼里主站真正的性能工程师是这样的:
1、熟悉Java(包括JVM内在机理)/c/c++。理由很简单,主站大部分的外围应用和中间件都是JAVA写的,底层核心系统是c/c++写的。
2、精通linux管理和shell编程。理由更简单,我一直觉得,shell熟练与否非常大程度决定了一个工程师的工作效率。
3、对数据库管理和性能优化有自己的实践和心得(数据库永远是个性能要点)
4、精通某一个性能测试工具。不止是使用,更包括原理,如何改造扩展。
5、熟悉linux kernel的实现(比如内存管理、文件系统、系统调用… )。这条感触在最近两个月特别深,可能是受到褚霸、子团等大侠们的影响吧,如果不熟悉kernel,确实很难在底层系统的性能测试上有所真正建树。其实这块也算是整个质量保证部的技术短板吧,现在淘宝的linux内核组都是自测+他人review的形式,如果。。。^-^
6、了解常见硬件,特别是存储相关。这块主要是受国外Percona公司的Peter和Vadim影响,他们能成为世界公认的mysql性能专家,他们熟悉mysql源码当然很重要,但也与他们那非常渊博的底层硬件知识是分不开的。
当然以上都是我个人意见,从我自己的角度出发看的问题。其实性能测试还有很多领域,比如前端性能测试这块,我是小白,就不发表任何相关意见了^-^ 但说到底,做性能这块关键一是经验积累二是掌握相关底层技术
至今还记得百淘65期让我最为难忘的细节,达人青云在分享他的牛P经历时总结到的:
● 结合优势,做别人做不了的
● 发现问题,做别人没做过的
● 主动出击,做别人不爱做的
希望自己能一直铭记这三句话,有天能成为一个真正的性能工程师
功能测试或集成测试是关系到整体系统功能的测试,而不只是牵涉到小段代码(单元)。这需要将已经单独测试好的模块组装起来,以保证其连接时也能像预期一样正常
工作。
JUnit是进行Java程序测试最常用的测试框架。
大多数Java开发人员都善于解决逻辑结构测试问题,比如如何建立测试预设环境、利用断言?添加测试方法、用setup方法进行初始化等。然而,如果Java开发人员能更深入地了解如何设计功能测试集来有效地检验代码是否正常运行,他们将获得更多的益处。
这篇文章介绍了可以建立有效 JUnit功能测试集的策略。包括:
确定测试用例覆盖所有程序行为。
确定代码入口点:测试程序整体功能的主要代码段。
匹配入口点与相应的测试用例。
根据初始化 /运行/检查流程创建测试用例。
设计并利用运行时事件表进行测试。
我将结合Saxon(一个可以处理XPath、XQuery和XSLT 的XML工具)的源代码来具体阐述这些策略。Saxon由约50000行Java代码组成,它是开源的,代码风格优良,注释文档详尽。
确定用例
功能测试有两个相辅的目标:覆盖率与粒度。为确保完整性,功能测试必须覆盖程序提供的所有功能,且必须在各组件水平上分别进行测试。一个测试可以建立在另一个测试的基础上,但任何测试都不能用来验证两项功能。
建立一个全面的功能测试集,第一步是列出程序可以实现的所有行为。这可以通过使用特定的用例模拟外部因素(程序使用者或其它软组件)执行系统内部的功能来实现。
一个典型的企业Java程序应该包含各种用户所需的详细文档,包括用例说明、非功能性要求、测试用例说明、用户界面设计文档、模型、用户个人信息以及其它各种人工生成的信息。一般来说简单的应用程序只有一个简单的说明文档。
借助这些文档,你可以快速确定需要测试的用例。每个测试用例都描述了应用程序可以执行的一项功能。用规模相近的测试方案确定唯一的功能是一个好习惯,而较大的方案可以根据其检验的功能拆分为较小的方案。
有许多种建立用例模型的方法,其中最简单的便是输入/输出匹配法。在Saxon的query类中,最简单的用例是传送一个查询文件、一个查询请求和一个输出文件路径。输出文件若不存在,将根据要求创建,并在文件中显示查询结果。
更复杂的用例可能需要输入更多的信息或输出更多的结果。然而,用例并不关心功能是如何在内部实现的。对它们来说,软件就像是一个 “黑盒子”,只要运行正常,即使真正实现软件功能的是盒子里的侏儒也无所谓。这是很重要的一点,因为输入/输出匹配用例很容易直接转换为测试用例,使得复 杂的说明与简单的测试吻合,确定该运行的功能正常运行,而不该运行的功能如预期一样失效。
如果类相对比较简单,或者已有列举类所有功能的说明文档,为指定入口点描述用例将很容易。如果不是这样,或许就需要研究类可能有的所有行为(确定类的目的与用法)。如果你想知道所有调用代码的地方,也可以从代码中提取用例。
最可能的情况是,根据开发人员提供的类的一些基本说明文档,可以完全确定这些类应有和不应有的行为。基于此,设计一套准确的用例集。
转换测试用例
每个测试用例都由两部分组成:输入和预期输出。输入部分包括所有创建变量或为变量赋值的测试用例语句。预期输出部分则表明应该得到的输出结果,它应该显示断言成立或“没有异常”(不存在断言语句时)这样的信息。
基本的输入/输出模式是理解测试用例模型最简单易用的办法。它采用一般函数(传递参数,获取返回值)和大多数用户行为(按某个键实现某项功能)惯用的模式。然后,可以用该模式进行:
初始化:建立测试预设环境。代码初始化可以在测试开始时进行或通过调用setUp()方法实现。
运行:调用被测试的代码,记录所有值得注意的输出和数据。
检查:使用断言语句确保代码正常运行。
举例来说,假设要测试Saxon库的转换类入口点。其中一个用例是将XML文件转换为HTML文件,当然前提是已有描述这个转换的XSL文件。输入这三个文件的路径,就应该输出HTML文件的内容。这可以直接转为下面的测试:
public void testXSLTransformation() { /* initialize the variables (or do this in setUp if used in many tests) */ String processMePath = "/path/to/file.xml"; String stylesheetPath = "/path/to/stylesheet.xsl"; String outputFilePath = "/path/to/output.xml"; //do the work Transform.main(new String[] { processMePath, stylesheetPath, "-o", outputFilePath } ); //check the work assertTrue(checkOutputFile(outputFilePath)); } |
每一步都可以根据需要进行增减。这里声明的变量也可以简单地通过调用方法来赋值。预期输出的实现是由几个步骤组成。如果成功得到预期输出,有时可以省略检查步骤。
虽然这个模式简单且灵活可变,但是第二步必不可少。这个模板没有告诉我们寻找要测试代码的方法,也不能保证代码以方便测试的方式运行。这是个需要认真考虑的问题。
功能测试
通过确定执行程序功能的主要代码段,可以将测试建立在一个更有效的环境下。由于这些类提供了从系统外部进行测试的途径,所以也是代码的入口点。
因此,功能测试的整体目标就是确定一组可以访问系统功能的高层接口类。这些类的独立性越高越好。毕竟,如果能将类从环境中分离出来,测试起来会更加容易。
确定作为入口点的代码是一个简单的过程。在代码库中,通常有几个控制该库所有功能的入口点。这些外部类作为客户端代码,与库的中介对象将开发人员从复杂的代码分析中解脱出来。这些便是应当首先对其方法进行测试的类。
比如,Saxon有一小组类作为逻辑入口点提供对库的访问。通过对外部类进行编码操作,比如转换、设置和查询,客户端代码可以访问库的许多功能 类,而无需考虑类的接口问题,甚至无需担心这些类是否存在。这些外部类用高层易用的接口提供一个简单的方式对系统功能进行测试,这正是一个优良的库的特 征。
程序代码中的各个功能模块通常是各自独立的。在某些代码中,甚至可以认为这些模块各自对应不同的、可通过大量外部类访问的库。这些类查找高层接口的逻辑位置。插件结构通常都采用这种设计模式:每个插件程序都有一个可以有效执行内部代码全部功能的简单接口。
在一些非严格描述的系统中,通常有一个所有程序行为的中介点。在MVC架构中,这个中介类一般作为“控制器”,负责配置系统各部分的请求路由。整体系统的功能主要由这个控制器连接的类实现,因此,这些类是测试的主要对象。
比如在 Applet程序设计中,java.applet.Applet的派生类就是所有代码的中心处理单元。根据代码的分解程度,测试焦点可以放在Applet 子类或与其连接的类上。
连接各个模块的代码也是测试的主要对象。将应用程序请求转换为数据库查询的类,以及有相似功能的适配类是其次应该考虑的测试对象。
各种基于MVC(模式-视图-控制器)架构的组件可以用其它的测试框架(比如Junit的扩展)进行测试。例如,Struts的 action类就最好使用JUnit的扩展StrutsTestCase进行测试;服务器端的组件(如Servlets、JSP和EJB)最好用 Catus进行测试;而HttpUnit则是对Web应用程序进行黑盒测试的最好框架。本文讨论的所有技术都可应用于这些框架环境下的测试。
从用例到测试用例
每个入口点都必须与相应的用例匹配。某些情况下可以忽视这一步,因为类名的自记录可以实现自动匹配,比如 Saxon中的转换类可以实现XSL转换,查询类可以进行XQuery转换。
其它情况则要复杂得多。通常用例描述的功能只能以横切关注点的方式存在,不能用任何单独的类进行例证。只有几组类交互时或满足一定条件时,才能观察到功能行为。这种情况下,测试的初始化程序会比较长,或者可以用 setUp()方法提供需要的测试环境。
而调用代码的运行程序应该尽可能地设计成一行,以减少与被测试代码的关联,这可以有效避免对边缘效应与不稳定实现细节的依赖。测试的检查阶段是 最复杂的,因为这个阶段经常需要添写非测试用代码。测试时可能需要对结果进行严格的分析以确保其符合要求。有时甚至需要将这个过程分为几步来完成,以取得 测试可以识别的结果。在XSL转换中,这两种情况都是可能的,结果储存在文件中,然后以XML格式读入内存并进行准确性分析。
Saxon中有个相对简单的例子。已有XML文件和XPath表达式的情况下,Saxon可以执行表达式并返回匹配列表。Saxon中的XpathExample样本类就是用来执行这种任务的。基于以上分析,可以设计如下的测试流程:
public void testXPathEvaluation() { //initialize XPathEvaluator xpe = new XPathEvaluator( new SAXSource(new InputSource("/path/to/file.xml"))); XPathExpression findLine = xpe.createExpression("/some/xpath[expression]"); //work List matches = findLine.evaluate(); //check assertTrue(matches.count() > 0); } |
两次输入的都是字符串常量,输出的则是所匹配的列表,可以用来验证匹配结果的正确性。这些工作都由一行代码完成,这行代码只是简单地调用了被测试的方法。
另一种可能的情况是XPathEvaluator没有调用createExpression()方法。因为表达式不存在,这时可能会显示错误信息。
将输入的源文件名和表达式保留在测试用例中不是个好习惯。某些项目(服务器名、用户名和密码等)不应该出现在测试文件中,它们应该可以根据情况 自由设置。并且,测试用例的设计应该方便测试驱动和测试数据的分离、测试驱动对大范围数据的可重用性和测试数据对测试驱动的可重用性。另一方面,不要将一 个简单的测试用例实现设计地过于复杂。一般来说,测试用例已经说明了系统的大部分状态,并可对其进行参数描述,所以无需在测试中进行过于详细的参数描述。
许多代码段可能出现在不止一个测试用例中。有经验的面向对象开发人员会尝试对其进行重构并创建通用类和有效方法。有时候这样做非常有用,比如登录过程应该设计成所有测试用例可用的方法。 但是,不要过度设计测试,这些Java类仅仅是用来验证应用程序的功能行为而已。
测试用例是脆弱的。比如,如果开发人员更改了testXPathEvaluation测试中输入文件的位置,或者creatExpression方法签名有所变动,测试脚本就会失效。
对于应用程序的测试用例实现来说,大量的重复性工作与改动是不可避免的。因此,可跟踪性对于所有的测试用例都是至关紧要的。出现问题的时候,如果能为开发人员指出相应的测试用例说明和用例说明将有利于提高修正bug的速度。
因此,测试用例注释中应标明原始说明文档的引用位置。这可以是一个简单的代码注释,也可以对每条测试都注释相关用例和所测功能,这样当测试出现问题时开发人员就会收到一条相关信息。因此,在代码中加入参考并维护可追踪性是很重要的。
设计运行时事件表
要了解测试覆盖的范围,必须先了解所测试代码如何运行,以及各种静态类如何形成描述程序状态的动态对象图表。
有许多模拟这种行为的方法,包括Granovetter图和物件互动图。其基本思想是用图形化的方式研究代码以了解测试中涉及到的运行时部分。 这些技术都可用运行时事件表(Runtime Event Diagrams)来描述,因为这些图表显示了程序运行时发生的事件,而非理论上类可以控制的事件。这些图表非常重要的原因包括:
首先,这些图表便于从高层上理解代码,并提供有用的说明文档。这个文档与代码的内联文档不同。这些图表显示代码的运行时表现,是产生代码功能的地方,也易于对系统的了解;大多数设计模式和架构在用对象和参考表示时要比用类和域表示容易得多。
另外,这些图表将测试执行的代码分类列表,并确定测试是否会受到将来对任意代码改动的影响。如果开发人员确定测试A是建立在B、C和D的基础上,她就可以确定如果对B、C或D做出改动就需要对A进行重新测试(确保向后兼容)。
以尽可能少的步骤模拟系统是个好方法。总的来说,实际调用与此无关,重要的是系统如何作为整体运作以获得预期目标。可以用简化的模拟系统实现这个目的,该系统只关心对象间的基本交互,并用自然语言描述交互中发生的事件。
做出运行时事件表后,就可以将其整合到类文档中。需要注意的是,为表添加一些限制可使其对类的修改更有弹性。首先,一般不能使用方法名,因为它 们会随时间发生变化。取而代之的是更易理解的自然语言描述。其次,这些图表主要是关于系统中各部分的交互。这是高层架构上的设计方案,一般不会再做改动。 最后,图表是建立在类型而非特定类的基础上。只要基本类型不变,为维持交互协议的正常运行,这些图表就不需要更新。
一旦图表创建成功,可以在许多方面获得应用。比如,一个图表可以用来获取系统如何运作,以及如何运用其交互部件实现功能的概览。在某种程度上这是一种简化了的UML语言,它只描述关系到整体功能的系统部件:实例及其类型、其它引用的实例,以及组件可以实现的功能。
这些图表也可以用来分析系统的复杂性以及如何进行简化。要确定简化系统的方法,可以查找系统中使用过一到两次的对象,并为其寻找其它可能更合适的位置。也可以查找重复的任务,将其封装到方法或类中。
然而,最重要的是图表在测试中的应用。通过对系统状态的总结,图表可以帮助解决系统中出现的问题。出现问题时,图表中的信息便可用作参考。因为 只需要将系统目前状态与预期状态作比较即可,这样确定问题产生的原因也就变得比较简单了。对小组件的改动不应该影响整体架构,因此可以通过对照运行时事件 表以保证系统仍然正常运行。并且,当有重要组件发生变动时,可以用运行时事件表对照系统当前状态以获取系统修正方案。由于将系统作为整体和对预期功能的描 述,运行时事件表也可以看作是一种结构化的单元测试。如果系统有变动,可以更容易地做出修正以维持系统的正常功能。
如果经常因细节问题影响对全局的把握,就应该使用图表。其高层本质可以用来分析软件的设计模式,就像反模式一样。还有许多其它用途,并且当运行时事件表、测试用例说明和用例说明没有描述所需的细节时,它还提供了直接进行代码分析的路线图。
利用功能测试进行回归测试
最后,为回报你在功能测试上做出的努力,配置一个与自动生成的程序相应的自动化测试程序。这个程序不只从功能上测试代码,还可以同时进行常规的 回归测试。现在大多开发项目都建立在庞大的代码库基础上,如果不能对代码库进行充分测试,开发团队将无从决定对程序的修正是否会破坏现有的功能,结果就是 很难对这种代码进行扩展或优化。与此相反,如果开发人员可以在全面的功能测试基础上进行回归测试,优化或扩展代码时就不必担心可能会引发不可预料的问题。 毕竟,没有比做完回归测试后发现一切正常更令人心情愉快的事了。
写TC貌似是很简单的
工作,但当动手写的时候往往会出现,不知道写什么,又感觉有一堆的东西需要写,即使一个简单的日常也会觉得里面的逻辑非常复杂,然后就是晕得不知所向。
个人认为,写TC没有固定的模式,也没有唯一的答案,每个人的方式不同,习惯不同,TC中的如何分类归纳也就自然不相同。但目标是一致的,基本目标是覆盖需求、无盲区;加强目标是加深测试点,完善用户友好性等。
下面分享下我写TC的几种思路。
第一种思路——先对象,后流程
面向对象是在平常入门学习中 首先接触到的概念,它不仅仅存在于代码的编写中,更存在于我们的工作方式和方法中。首先分析需求中涉及到哪些对象,比如页面是一个对象,对它加以细化,页 面大对象可能又分为新增页面,修改页面,删除页面和查询页面等,或者从功能上划分为卖家页面、小二页面等。分析完后再层层细化,比如新增页面包含的哪些文 本的输入框,单选/多选项、日历控件,以及它们之间操作的优先级,错误提示的优先级等等,再洗化到各个控件本身的限制检查,如单行文本最长和最短的校验长 度是多少,非法字符校验等。
当所有对象类信息完成后,再考虑这些对象之间的流程关系,比如对用户身份审核的操作必须建立在用户身份信息 已创建之后,或者信息被修改后。不光是需要校验正常的操作流程,还需要花大精力放在异常流程的操作上,比如用户在填写信息时,突然中断了操作,这样的情况 通过什么样的流程去处理。因此这里的流程,应该是包括正常流、异常流及扩展流(需求中未涉及,但测试人员基于用户友好或者性能方面考虑需要加入的流程)。
回过头想一想,我们说,把面向对象的思想带入TC,那面向对象又体现在什么地方呢,难道仅仅是分类么?NO!
我们是不是经常会在写TC中碰到这样的问题,比如某些项目中,进行查看和修改时,发现自己看到的是相同的页面,也就是可能在做不同操作流程的时候发现到 达了相同的一个出口,那对于这N个流程是否需要写N个平行的TC,是否可以把某部分写成公共模块以提高效率,避免冗余呢。
第一种思路可 能会有同学觉得很麻烦,很容易复杂化,确实是的,因为大家平常做项目或日常时,至少是有页面或者页面大概的原形,如果需求是很模糊的,又或者客户也不知道 具体是要做成什么样的,同时客户又希望能快速立项的情况下,可以使用这种方式,其实在这样的过程中,测试人员无形中担当了架构的角色,并且能帮助开发完善 产品。
第二种思路——先流程,再对象
这种思路,要求是页面设计到位,至少是大概的原形具有,然后对着原形写TC。
从打开的第一个页面开始层层深入写,比如首先是用户登陆,然后是主展示页面,再可能是搜索宝贝等,先把流程正常流程建立好,然后将这些流程细化,如用户 登陆是否采用弹出窗口,窗口的位置、大小,窗口中的表单项是否完整,如是不是缺少验证码项,再考虑某一项的校验,如用户名是否为单行文本,长度限制多少, 非法字符限制,是否为必填项(不填是否有提示)等。
使用这种思路的时候,切记至少要包含几类信息:页面总体展示、表单项完整性、表单项正确性、表单项可操作性(独立操作和组合操作)、表单项非法校验、及当前页面的其他跳转出口(如点击“登陆”,在用户输入的信息正确的情况下,应跳转到主展示页面)。
这种思路可能使用的同学比较多,至少我是经常用的。这里实际上还是把页面当成了大对象,当出现多类页面跳转到相同页面上去的时候,这个相同页面就可以作为公共部分来使用了。
记得在学校里学习这些原理的时候,对它的用法感悟不深刻,出来工作以后发现,其实很多思想就穿插在平时的应用中,所以有一句话很欣赏:解决问题,思路很重要,技术在其次。
以上是对于写TC思路的一些个人看法,有不足之处还请大家指正。
一直在做功能测试工作,负责过三四个不大不小的项目的功能测试工作,却很少静下心来总结工作中的得失。
很多不了解测试的人,认为功能测试不过就是拿鼠标点来点去,没有什么技术含量,随便招个应届毕业生就能干的工作。我也曾经认为功能测试没什么前途,现在 看来觉得自己太浮躁了。功能测试的门槛可能比较低,做测试工作的人大多都是从功能测试开始,但要做好功能测试却不容易,需要学习的知识还很多,比如操作系统、数据库、网络。下面主要结合工作实践谈谈我对功能测试的一点总结。
功能测试最重要的是理解业务和需求。知道系统要实现什么功能,业务流程是怎样的,然后就可以根据需求编写测试计划和测试用例了。测试书籍上介绍常用的编 写测试用例的方法有:等价类、边界值、因果图、判定表等,在实际工作中,我使用较多的有等价类、边界值、场景法和错误猜测法。在这里需要提一点,将测试用 例按测试目的进行分类,比如用户界面、功能点、业务场景等,会让测试用例的结构看起来更清晰,执行测试用例的效率也更高。
要做好功能测 试,还需要对整个系统的数据库结构比较清楚,每个功能点涉及哪些数据表,对数据的操作方式是怎样的。这样就不单从前台页面来进行测试,通过对数据库中数据 的验证,可以发现隐藏的一些bug。比如库表没有进行关联删除,从前台页面是看不出来的,但实际可能导致程序出现问题。对一些比较复杂的组合查询或数据排 序,也可以自己编写sql语句对结果进行验证。
除此之外,了解程序的框架结构和一些开发知识也有助于更好地测试程序和定位错误。做完一个业务,可以通过系统日志来查看错误原因,结合数据库结构,可以更好帮助开发人员定位错误。比如日志记录执行哪条sql语句出错了,错误的原因是字段长度设置不够。我在这方面做得不太好,现在在努力学习一些开发知识,期待在以后的工作能做得更好。
最后,对bug的分析和总结有助于积累测试经验。比如哪种类型的bug数量多,哪些测试用例发现的bug较多,有助于测试用例的编写和修改。在探索测试 时,发现bug的测试过程也要加入测试用例库中。通过测试用例的累积,可以更好地了解系统常出现的错误,积累更多的测试经验。
功能测试(「unctiona!Test)通常使用
黑盒测试的方法—将程序视为一个不能打开的黑盒,在完全不考虑程序内部结构和内部特征的情况下,从软件产品的界面、架构、接口出发,输入预定的数据,在预期结果和实际结果之间进行评测,并判断软件产品是否符合用户需求。
使用黑盒测试方法的功能测试流程简述如下:
1.确定参照体系,参照体系是软件测试的判断依据。对于不同的实现,需要参照体系明确正确的实现方式。功能测试中,参照体系的角色通常由需求规格说明书来担当。在更为细致深入的测试中,还可引入系统设计文档等。
2.用例编写,测试用例是有条理、有组织的,对于测试行为的描述。测试用例描述了测试执行时,执行者所应进行的具体操作。测试用例应严格按照需求文档进行编写。
3.测试执行,测试者执行测试时,应按照测试用例所描述的内容进行操作,并将产出的结果与测试用例中的描述进行对比,并判断测试结果。若测试未通过,测 试者应将该步骤的测试结果判定为失败,并提交缺陷给相应的开发人员,并在后续的测试中,追踪该缺陷的修复情况,直至该缺陷被修复。
4.测试用例维护,测试用例不是一次性产品,应不断进行调整与更新。一份维护良好的测试用例,不但可以大大加快后续回归测试的速度,更可让新入职的员工—不论测试还是开发,能够更快、更方便的熟悉业务。
比起需求文档的错综复杂、面面俱到,经过编写人员的理解、提炼而成的测试用例,是一份需求文档的精华摘要,阅读的有效性更高。测试用例对于项目而言,是 一份非常宝贵的资料。整个黑盒测试过程看似简单,但由于大部分程序难以做到与需求文档严格一致,而需求文档也无法做到对于程序的每个细节都进行详细说明。
测试过程中,测试人员应当依据经验、常识等进行判断,某个和测试用例描述的期望结果不完全一致的实际结果应判定为通过还是失败。
在测试执行过程中,测试人员对于测试用例的态度应尊重但不迷信。虽然测试用例是经过仔细编写和详细评审的,但错误依旧难免。因此,作为测试执行者,不应 进行机械测试,而应多动脑,能够站在用户、设计人员的角度看问题,这样不但可以发现一些测试用例中可能存在的问题,还能发现更多测试用例中没有涵盖到的缺 陷。
继续深入阐述几个测试用例编写中需要遵循的原则,总结为如下五点:
1.正确性,正确性是测试用例编写中的最基本原则。测试执行时,测试者的操作是基于测试用例的。因此,一旦测试用例存在错误,将对测试者产生误导,影响测试判断的准确性,从而产生缺陷误报或缺陷遗漏。
2.可读性,前文对于这点已进行较为详细的阐述。由于测试用例面对的读者众多,因此,一个优秀的测试用例的最基本要求是能够让他人理解,不会因为表述上的问题产生歧义。
3.完整性,完整性是对正确性的补充。完整性要求测试用例能够覆盖到整个软件项目的每个模块、每个功能、每个细节。完整性缺失的测试用例,后果或比缺复杂工作流软件自动化测试方法的研究第二章件测试理论,J技术基础失正确性的测试用例更为严重。正确性的缺失影响的通常是一个功能点,而完整性的缺失则会影响整个模块。
4.可执行性,可执行性是指用户能够按照测试用例中的测试步骤描述,进行测试的执行。为此,步骤描述必须清晰完整,测试用例的拆分设计也必须思路清晰,结构合理。
5.一致性,一致性指依据测试用例的描述执行测试时,操作与产出结果应是一致的。测试用例应减少操作者的主观性,增加操作的确定性。这样才‘能让功能测试的结果更为客观,让后续的回归测试结果更为精确。避免因为测试者的变更,导致测试结果的改变。
一个设计良好的测试用例应当符合以上五点。前两点更多针对编写者的编写技术与细心程度,而后三点则更多与用例的设计方法有关,因此,后文对测试用例设计方法的论述中,将着重以后三点作为评定标准,比较设计方法的优劣。