开始之前
本文侧重讲述如何在iOS程序的开发过程中使用单元测试。使用Xcode自带的OCUnit作为测试框架。
一、单元测试概述
单元测试作为敏捷开发实践的组成之一,其目的是提高软件开发的效率,维持代码的健康性。其目标是证明软件能够正常运行,而不是发现bug(发现bug这一目的与开发成本是正相关的,虽然发现bug是保证软件质量的一种手段,但是很显然这与降低软件开发成本这一目的背道而驰)。它是对软件质量的一种保证,例如重构之后我们需要保证软件产品的正常运行。
很多人认为编写单元测试没有用是认为单元测试并不能保证一定能减少bug发生的几率,而由于编写单元测试一定会花费一定的时间与精力,因而必然的会增加成本。客观的说,造成这种原因很大的程度上是程序员的水平不够高。我认为使用使用单元测试带来巨大好处的必要条件如下所示:
● 程序员本身的编程水平--是否有较多的代码经验,是否熟练掌握重构
● 程序员对项目的认知--是否能正确理解软件或模块的需求
● 项目质量--是否稳定,是否长期多版本,是否需要应对较多变化
如果程序员水平较高,对需求理解较为清晰,项目需要面对较多的变化,那么毫无疑问单元测试对于软件非常有益。假如软件功能简单且开发周期短,不需要进行复杂的维护工作,那么单元测试的意义并不大。
优秀的单元测试实践的好处:
● 好的单元测试就是一份好的文档,并且比文档更能为程序员所接受,它直接描述了测试员对受测代码的结果所持的预期。
● 当代码由别人维护时(或自己进行重构时),通过单元测试的约束,才能保证在加入新功能或修改旧功能时代码的正确性。
● 由于单元测试的自动化执行,保证了在整个开发流程中代码都会被测试,这非常符合XP思想。
● 保证在面对软件功能的变化时,程序员可以较为放心的进行代码重构,而不必担心是否破坏了原有功能。
● 好的单元测试可以降低bug数量,而对于项目管理来说,修改bug这个过程是无法制定计划的,可以使软件的开发流程更容易掌控。
● 可以由老程序员编写描述某个类行为的测试,以此指导新程序员对类的编码。
● ……
好处还有很多,但最重要的一点就是保证了软件质量的同时,由于减少bug和应对变化造成的回归bug的产生等,提高了劳动生产率。而且,在敏捷流程中,使用单元测试是必须掌握的手段,否则就没发保证重构的正确性,从而造成代码无法面对变化。
二、iOS的单元测试概述
刚接触客户端编程时,我在很长一段时间内都想不通对于客户端程序如何编写单元测试。单元测试本质上说白了就是用一些断言来判定结果,而这种方式是如何应用到具有复杂交互的界面测试上来的呢?
我们要做的就是将客户端代码转化为易于测试的代码。什么样的代码易于测试呢?它至少是这样的:
1、被测方法需要产生可测量的结果。
2、类之间的关系应该是松耦合的。
其中第一条是必要条件。使用断言这种形式指明了测试的方法最终要造成某些可以度量的结果。因而,我们需要尽量的将展示和业务逻辑分离开来。展示的代码是没法测试的,例如有的方法只是播放动画。而业务逻辑最终都会造成一些数据的改变,这是容易测试的。
大略的讲,作为一个iOS程序员来说,首先要了解一个叫做MVC的模式。这个模式定义了Cocoa Touch框架的总体结构。在iOS程序中,我们也需要按照这种模式进行界面代码的编写。这样设计出来的类具有较好的结构,且比较适合于做单元测试。
然后一定要懂得不停重构代码,这样我们才能使代码不停地改善,不停地变得更加适合单元测试。
有一些框架可以帮助大家更好的测试,分别是OCUnit、GTM、GHUnit、CATCH、OCMock,但目前对我来说,OCUnit足够用了。作为苹果官方提供的测试框架,它最大的优点就是简单易用。
三、单元测试实践
下面是一些我所理解的单元测试中比较好的实践。
顾名思义,单元测试面向的对象是单元,这个专有名词源自编译器领域的术语“编译单元”。在面向过程中,指的是函数,而在面向对象中,指的通常就是“类”。因而,每个功能类都应该提供对应的单元测试。
实践1:每个功能类都应提供单元测试,且每一个测试类,只依赖于其要测试的受测类。使用伪造对象可以避免对其他类的依赖。
解释:保证一个测试类只关注一个被测类,当测试不通过时,就能迅速的定位到是谁发生了错误,而不会受到其他类的干扰。
简单的数据类等可以不提供,但是要保证该测试的都要覆盖到。并不存在一种合适的度量指标可以量化地判断某种单元测试方案是否成功。常用的标准(代码覆盖率和成功执行的测试用例数)都可以在受测软件的质量不变的情况下人为的修改(作假)。当然,在无法确保程序员素质的情况下,作为没有办法的办法,使用这种标准也是可以的(或者无奈的说,必须的)。单元测试需要程序员自己把关,关注哪些功能确实需要测试覆盖。这也就是前面所说的一些程序员不相信单元测试可以提高生产率的理由--它更多的依赖于程序员的素质,这是没有保证的。但同样的,由于敏捷是一种以人为本的思想实践,因而这种行为似乎又是一种必然。
实践1.1:使用伪造类避免对其他类的依赖。
解释:避免依赖的一种手段。
例如,某个被测的方法声明是这样的:
-(void)xxxx:(Person *)person;
如果测试时传入Person的话,就造成了测试类依赖于两个类。当由于person中的错误引发测试不通过时,就不能迅速的定位到受测类中是否有问题。遇到这种情况,就可以使用伪造类。假如方法中只使用了person的一个属性name,那么可以将方法名重构为
-(void)xxxx:(id)person;(此处id有待商榷,只是这样做最简单)
然后在单元测试的target中添加只包含name属性的fakePerson来作为伪造类。这样,一旦发生错误就可以迅速的推测出错误的来源。
实践1.2:使用伪造环境避免其他环境的干扰。
解释:适合于异步的方法测试。
很经常遇到的一种情况是测试有网络环境的代码。由于异步的存在,这会造成测试代码不好写。一种简单的解决方法是,我们假定网络一定是通畅的,则我们测试的代码将分为两部分,即拼装发送功能和接收解析功能。假如发送和接收功能各自都能通过测试,那么我们大约可以确定这个异步方法的正确性。另一种方法是使用GHUnit,它支持异步代码的测试。
实践2:测试用例(方法)名应该是自解释的且是独立的。
解释:基本功。
如果被测试类的名称是XXX,那么测试类可以命名为XXXTests。而对于其中要测试的功能,命名应该是自解释的。这可以在发现错误时尽快的定位问题所在。例如,如果某个属性obj应该是非空的,那么我们可以将其命名为:
-(void)testObjNotNil{}
每个方法目标应该是单一的,大多数情况下每个方法内都只有一个断言语句;方法不应该依赖于其他方法的结果作为输入,保证原子性。
实践3:断言语句需要解释测试者的意图。
解释:基本功
每种单元测试框架都提供了很多断言语句,从根本上来说它们都是一样的。但是测试者需要根据自己的目的选择适当的语句,这样才可以让别人阅读测试代码时理解用例设计的目的。例如对于STAssertNil和STAssertNotNil等等。
实践4:判断某个意图有没有达到的很好的方法是检测方法影响的数据有没有合理的变化。
解释:基本功
由于单元测试是使用断言语句来做判断的,因而最容易做的就是判断数据的变化。这也就限定了单元测试能测试的方法范围,即引起数据变化的方法。对于一些纯展示的方法,例如播放一段特效,这种方法是无法靠单元测试来进行约束的。测试数据的特性包括取值范围(int、float等),排列顺序(NSArray等),类型等等。
实践5:运用重构的手段使方法变得易于被测试。
解释:单元测试是保障重构安全的手段,重构也可以使代码易于被测试。
什么样的代码是容易进行单元测试的?最简单的一点就是,每个被测方法都应该是功能单一的。当然,这也是代码规范中应该做到的。方法的功能单一,则测试方法的断言也会比较好确定。如果你发现某个方法很难进行测试,则就应该对这个方法进行拆分重构。
实践5.1:面向抽象设计类之间的关系。
解释:利于伪造类的实现。
类之间通讯如果依赖于抽象(接口),则可以较容易的使用伪造类。参照实践1.1。
实践6:运用自上而下的方式构建类。
解释:自上而下的方式可以使类的功能明确,类的构成将会清晰紧凑,不会出现一些废方法。
先确定类需要负担的责任,以此来确定类具有的公有方法以及属性。通过重构将公有方法中的代码转化为私有方法,以使方法尽量短小紧凑。
实践6.1:应对所有暴露的属性和方法提供测试,私有方法则不必。
解释:如果运用自上而下的方式构建类,则理论上私有方法应该都是公有方法重构而得到的。实际上测试公有方法时这些私有方法都应该被测试到了。而且,由于私有方法相对公有方法来说发生变动的可能性很大,会造成不必要的修改测试代码的成本。
回调方法不属于私有方法,也需要进行测试。
实践6.2:回调方法的测试方法是直接调用。
解释:基本功
由于回调方法一般是异步和不可触发的(按正常流程),例如网络事件的返回和按下按钮的触发事件。因而,测试的时候要直接调用来对其流程进行检测。例如某个按钮的touch up inside事件:
-(void)buttonPressed:(id)sender;
可以根据方法中用到的方法、属性伪造一个FakeButton按钮作为参数传递进行测试。
实践6.2:测试私有的方式,KVC、子类化和类别。
解释:基本功。
遇到需要通过验证私有数据才能编写的测试时,可以考虑使用KVC和子类化。子类继承于被测类,只包含于单元测试target,其作用就是在不该变受测类的情况下,使受测类具有某些易于被测的能力。
实践7:变化需要新测试的支持。
解释:保证测试的覆盖度。
就像敏捷中提到的“改变需要抽象”一样,在测试中改变需要新的测试。当然,度依然由程序员自己掌控。
四、一般流程
使用OCUnit最大的好处就是流程非常的简单,简单到让你觉得非常愉悦。由于有XCode的支持,添加测试变得异常简单。只要在新建工程时勾选“Include Unit Tests”,就会自动的加入一个示例。然后再需要添加新的单元测试时,新建一个“Objective-C test case class”就可以了。
测试文件中,只要知道setUp是初始化的地方,tearDown是结束清理的地方,而且它们在每个用例方法执行时都会重新执行--这保证了测试用例的原子性。然后知道每个测试用例都是以test作为前缀的,并且无返回值。然后在方法中编写断言语句就可以了。输入STAssertxxxxx就可以看到它们的联想提示。编写完成后,执行菜单Product->Test,单元测试就完成了!
五、测试驱动(TDD)
敏捷当中提到了TDD这种开发方式。TDD的主旨是使开发者对其编写的代码更有信心,使开发者修改代码时心里更加踏实。对于其总结,还是引用原文比较妥当:“测试驱动开发的妙处即在于,它以需求为引领,通过测试的形式,来指导开发者进行软件的设计与架构,并编写出最为精炼的代码,使得测试用例运行通过。经过适当的重构之后,测试用例与产品代码可达到较为健康的状态。”也就是上面提到的,通过自上而下的形式设计类,通过单元测试来不停地审视和重构类,从而达到代码的健康。
如果在代码写完之后在编写单元测试,那么就体现不出这种模式的好处了。这就好像写完代码再补文档一样,没有什么意义。测试应该在代码开始之前,或者在代码编写中不停地进行编写更新,这样才能使代码不停进步。这也正是TDD的意思。
六、总结
单元测试的代码如此简单,但是想写好单元测试却并不是一件简单的事情。它需要程序员比较深的功底。由于个人水平所限,有一些东西说的比较啰嗦。把复杂问题简单化是本事,任重而道远。希望大家可以在日常开发中运用好这种简洁高效的技术。
最后,作为一个中国人,祈福雅安。网上有一些人在这种事件上还在喷。我想说的是,虽然这个世界是客观存在的,但是每个人的世界观确是主观的。一个人观察世界的角度决定了他认为这个世界是什么样的。中华民族的民族性格是内敛的,在外在表现上似乎不如西方人张扬。但是就像汶川一样,全国人民在这种时刻表现出了我们这个民族内在的优秀品质。老鼠屎在哪里都是老鼠屎,我以自己是中国人为荣。
至今所不为熟悉的需求管理的基础
这则报道是以年轻IT工程师为对象(参加工作2-4年左右),以能够使其理解软件需求管理的基础为目标。为了描述更具体的内容,在本报道中提出了关于RUP(注)的需求管理成果物和作业流程,为了尽量使需求管理的基础更明了易懂,而要对其进行讲解。
(注:Rational Unified Process:是 IBM Rational的软件开发方法论,作为面向对象开发方法论而闻名)
为什么要进行需求管理?
为什么要进行需求管理?用一句话来概述就是因为管理需求可以很大程度地来左右项目的成功。首先,来考虑一般的项目目标吧。请看下面的定义。
出现了“满足顾客真实需求”“高品质”“期限内”“预算内”这4个关键字,但是无论哪个都与需求管理息息相关。首先、为了制造“高品质的产品”,在需求管理方面要准确地把握所谓的系统可靠性、可扩展性等非功能需求也是非常重要的。另外、对于在“期限内”“预算内”开发产品存在问题吗?项目必须在限定时间、预算以及资源的状态下开发。考虑利用所给予的时间、预算以及资源能够完成多少作业,必须把产品要求式样的范围控制在作业可能的范围内。
由于QCD(Quality:质量、Cost:价格、Delivery:缴纳期)这一关键字经常被使用,所以大家也就对“在期限内及预算内开发高品质的产品”更加耳熟了。在此想要让大家关注的是“满足客户真实需求”的部分。无论在期限及预算内制造了多少高品质的产品,如果不能满足顾客真实需求的话,那些产品也是没有意义的。
例如,开发为提高营业员业务处理效率的应用程序。在该项目中拥有高超技能的开发者进行了极优秀的设计,也充分考虑了其扩展性。但是,由于应用程序对于用户(营业员)来说非常难以使用,所以很多营业员都对其敬而远之。不久,该系统就会自然消失了。该产品没能反映所谓“提高业务处理效率”的顾客的真实需求。也就是说、缺少了满足该需求的部分(例如:使用 GUI的容易度)。遗憾的是这种事例经常发生。在此,我想在实现“满足顾客真实需求”之后来强调项目的成功挖掘。
另一方面、从数据中也能说明需求管理对项目的成功有很大的贡献。作为软件开发现场的调查报告,根据著名的(Standish Group的)CHAOS(2001年)报告,在对项目的成功完成贡献的原因一览里“用户的输入”“明确商务目标”“将开发范围最小化”“稳定的需求项目”等与需求管理相关的事项连接在上面。从此也能看出需求管理的重要性。
何为需求?何为需求管理?
在接触需求管理的具体内容之前,首先来看一下要求和需求管理的定义。在RUP中将需求和需求管理如下定义。
“需求”的定义非常简单。所谓定义需求就是定义“应该满足系统的样态和能力”。换句话说,可以说成定义“做什么好呢?”,这也可以说是定义了项目成功的基准。即使用一句话来概述需求、在需求里也存在着各种各样的种类和水平。但是我想在以后将对需求的详细定义进行说明。
在RUP中“需求管理”的定义中需要注意的是操纵需求管理的范围的宽度。所谓需求管理,首先包含“挖掘需求”。所谓“挖掘需求”就是从顾客和终端用户提出对系统的需求。通常、不会轻易提出需求,所以就变为使用各种手法来竭力发掘。
其次、所谓需求管理包含“整理需求”。如果是复杂的系统,存在几百件需求也是正常的,所以需要对其进行整理。并且,需求管理也包含“将需求文档化”。一般人都不能记住那么多的需求,并且也为了在客户和开发团队之间共享需求所以文档化是必要的。
另外,所谓需求管理也包含“形成并维护客户与开发团队之间的协议”。如上所述、如果能够“发掘、整理要求,并将其文档化”,接下来关于其要求,为了在期限内、预算内完成开发,需要在顾客和开发团队之间对项目中涉及的要求范围进行协定。另外、随着开发的进入而发生需求变更时要分析其影响范围,对于被采纳的以及与之相反的事项与客户形成协议也是非常重要的。
需求管理不简单
如果是2~3人规模的小项目,不会为需求而烦恼。但是小规模软件包开发中有几千件需求、大规模项目中有几万件以上的要求,随着规模的变大,在需求管理中要面对各种问题。如下所示:列举了项目中容易引发的典型问题。
---“很难发掘需求”
在很多情况下,如果开发团队不能充分理解应该解决的问题,就会提供给倾向技术的解决对策,从而制作成没有满足顾客需求的系统。为了不出现上述情况,挖掘客户的需求就显得尤为重要。但是由于客户与开发者之间持有不同的术语、背景、动机以及目的,因而存在着沟通上的分歧。
---“难以将需求体系化并整理”
由于在大规模项目中单纯地需求的数目非常多,所以涉及的事物本身很困难。另外、这些需求的出处也不仅仅是用户,也复杂地涉及到受系统影响的利害关系者(Stakeholder)。更进一步地说、在需求方面存在着多种种类和级别。关系到各种各样的成果物,所以体系化非常困难。
---“难以将需求文档化”
这既有没有明确需求的情况,也有难以把单纯的需求用语言来表达的情况。文档化是不仅困难、而且对记述高品质的需求文档缺乏评审,同时在需求变更时更新文档也需要花费大量的作业时间。
---“难以追加需求变更”
随着项目的展开、需求会进化并增加,有时计划会超出项目的日程安排和预算。最初的原因是客户频繁的需求变更,但是在开发团队的对应方法上也存在着问题。有时候不能分析需求变更的影响,不能与客户取得很好的协议。另外、把需求变更在开发团队的全体成员中共享也不是简单的事情。
如上、发现了很多问题,但是为了妥当地处理这些问题,要求对需求管理进行体系化的程序。下回、在开始需求管理具体的程序之前,先要了解一下要求的各个种类和级别。
第2回:软件需求的详细分类
在上回的 “至今所不为熟悉的需求管理的基础”中只接触了关于需求的非常模糊的定义。在这回我们来了解一下更详细的需求吧。首先看一看如何描述才能把系统需求完整记录,然后再逐步深入。
需求可以描述系统的什么内容?
定义系统的详细需求在RUP中称为“软件需求(Software Requirements)”。也就是说,如果完整的描述了软件需求的话,系统需求也就完整描述了。
软件需求定义是从把系统作为黑匣子的观点出发,描述系统为用户、设备或者其他系统提供的执行能力/状态的内容。也就是说,要描述软件需求的话,需要考虑从系统外部来了解的状态下(不知道系统中会变成什么什么状态),完整地描述其要执行什么。为了完整地描述系统,需要着眼于图1的5个范畴。根据定义图中的项目能够决定软件的全套需求。
不属于软件需求的事项
至此所说的软件需求就是将“从外部观点来看系统必须要做什么”传达给开发者的事项。说明了从系统的输入、输出、功能、非功能特性以及设计方面限制等的侧面来定义的事项。决定“系统会执行什么(What)”,但是重要的是不能决定“系统怎样将其实现(How)”。
另外,必须注意软件需求中不应该包含的信息。在软件需求中不包含关于设计和实现的信息、系统测试方法的信息以及与项目管理相关的信息等(图2)。
特别是关于设计和实现的信息,稍不注意就会介入,所以需要特别注意。如果需求中包含关于设计和体系结构的信息,则会被其信息所限制,对于应用程序来说就不能选择最合适的设计方法。但是,有时系统内部已经确定的场合也有。例如,因为组织许可方面的因素,明确了数据库必须使用DB2,这种情况下作为“设计限制(Design Constraints)”进行描述。
重要的是尽量减少设计上的限制。那样,开发者只在最小限度的限制下能够实现必要的功能、设计出满足性能和可靠性的系统。
需求的详细分类
关于软件需求之前了解的情况,使用一句话来概括也会有多种。特别是可以按如下所示分为3种。
1)功能需求
2)非功能需求
3)设计限制
另外,如图3所示通常取出Functionality(功能性)、Usability(易用性)、Reliability(可靠性)、Performance(性能)、Supportability(易支持性)的开头字母以FURPS+形式来分类。FURPS+中最后的+表示不包含在FURPS中的设计方面的限制。该FURPS+用上述3种分类来说的话,各自相当于F是功能需求、URPS是非功能需求、+是设计限制。
根据上述形式进行分类,形成识别需求时和评价对需求的理解时的检验一览表,可以防止遗漏和不完整性。
软件非功能需求
到前一节为止我们了解了所说的“软件需求”就是把系统在详细基准下定义的需求,从黑匣子的观点来描述系统能力的需求。另外软件需求可以用FURPS+方式分类。但是对于开发能够让客户满意的系统不仅仅是软件需求,掌握利害关系者的需求也是非常重要的。(利害关系者:拥有与项目有相关利害关系的人、特别是系统的用户被列举为重要的利害关系者)
众所周知,为了有效地执行需求管理,作为详细标准需求的“软件需求”以外也作为需求来掌握,这一事项在经验上是很有效的。也就是说,把需求的语言对象不仅仅是系统详细定义的“软件需求”,也扩大到了利害关系者的“原始需求(Needs)”。并且另外一点,作为比软件需求抽象标准更高的需求,把“功能特性(Features)”也作为需求来掌握。有点麻烦但是倒入“需求类型”这一概念,其类型之一包括“原始需求”、“功能特性”,“软件需求”。由于功能特性比软件需求的抽象度要高,所以如果利用功能特性的话,就能很容易地把握系统整体,也就能轻松地管理开发范围。
软件非功能需求
到前一节为止我们了解了所说的“软件需求”就是把系统在详细基准下定义的需求,从黑匣子的观点来描述系统能力的需求。另外软件需求可以用FURPS+方式分类。但是对于开发能够让客户满意的系统不仅仅是软件需求,掌握利害关系者的需求也是非常重要的。(利害关系者:拥有与项目有相关利害关系的人、特别是系统的用户被列举为重要的利害关系者)
众所周知,为了有效地执行需求管理,作为详细标准需求的“软件需求”以外也作为需求来掌握,这一事项在经验上是很有效的。也就是说,把需求的语言对象不仅仅是系统详细定义的“软件需求”,也扩大到了利害关系者的“原始需求(Needs)”。并且另外一点,作为比软件需求抽象标准更高的需求,把“功能特性(Features)”也作为需求来掌握。有点麻烦但是倒入“需求类型”这一概念,其类型之一包括“原始需求”、“功能特性”,“软件需求”。由于功能特性比软件需求的抽象度要高,所以如果利用功能特性的话,就能很容易地把握系统整体,也就能轻松地管理开发范围。
那样的话,如图4所示可以把原始需求、功能特性和软件需求在3段的金字塔状中按照每个需求类型进行体系化描述。以订单管理业务的应用程序为例,如图5所示按照各自的需求类型分别描述需求样本。
重新简单地总结一下“需求类型”吧。首先,为了能够准确地解决客户的问题,把在系统背后的“原始需求”以不依赖系统的形式来掌握。并且,以掌握系统大功能总括的“功能特性”为基础,来理解系统整体,也就容易进行开发范围的管理。更进一步说,以定义作为系统详细的“软件需求”为基础,开发者应该可以对系统进行设计、实现以及测试。特别是根据“原始需求”记录的事项、该“功能特性”最初是从哪里来的?“软件需求”是为了什么而存在的?具有这样的观点是非常重要的。比如,让开发者变更依赖内容时,从“原始需求”的视点来看,可以讨论实现方法和不用讨论实现方法,这两者存在很大差异。
那么,这回关于需求的分类进行了了解。下回对于需求管理程序的流程以及对作业流程图进行整理。
9.3.4 贯穿始终的缺陷分析
小艾完成调查表后,就去找凯文看是否有下一步任务。看到凯文正在画花花绿绿的表格,他就很好奇地问:"这是什么?"
凯文抬起头说:"我正在做项目最终缺陷分析,你来得正是时候,我正想给你详细介绍一下缺陷分析,好让你做个帮手。"
在凯文图文并茂地认真讲解下,小艾对缺陷分析有了深刻的了解。
在整个项目测试过程中,会不间断地做一些缺陷分析,来帮助监控在开发和测试中是否存在问题和漏洞,并根据分析结果来调整测试范围和策略。在最终测试完成后,会系统做一次缺陷分析,并以此总结经验教训以便在今后的项目中做出改进。
不同测试类型会有不同的缺陷分析侧重点。比如安装测试和迁移测试,会专注于分析产品安装在不同操作系统及数据库上出现的问题,所以会专门分析不同操作系统,不同数据库上出现的缺陷,看是否这个问题只发生在特定系统或数据库上。
一般来讲,所有测试类型都会对以下方面进行分析。
1、有效缺陷和无效缺陷的比率
前面的章节中详细介绍了缺陷管理模型中的缺陷生命周期状态及相关信息。 简而言之,缺陷从被发现到最终解决存在下列典型状态:关闭状态,开启状态,工作状态,验证状态,退回状态,取消状态。
其中,在关闭状态和取消状态下的缺陷称为完结缺陷,除此之外状态的缺陷称为活跃缺陷。项目结束时,理论上所有缺陷都应处在关闭状态或取消状态。当然由于时间原因,还存在极少量开启状态下的缺陷被延缓到补丁版本或新版本里修复。我们把关闭状态缺陷和延缓缺陷称为有效缺陷。而把取消状态下的缺陷称为无效缺陷。在测试过程中,应尽量提高有效缺陷比率,避免开出无效缺陷。
如图9-2所示,测试过程共发现103个缺陷,其中有效缺陷85个,占总缺陷的83%,无效缺陷18个,占总缺陷的17%。一般来讲,有效缺陷在80%以上就算是比较良好的。
造成无效缺陷的原因大致有以下几点:
重复缺陷:是指在系统里相同原因的缺陷已经被其他人报告。在此缺陷被作为重复缺陷返回时,先不要立即取消。必须等到核查修复后,才在系统里取消。这是因为有些缺陷被误认为是重复缺陷,实际上是不同原因造成的问题。我们只有在核查修复代码后,才能确认这是否是无效缺陷。
用法错误:是指测试人员在测试过程中有一些操作错误或对功能的错误理解而造成测试案例失败,由此开出的缺陷是无效缺陷。
符合设计:是指测试人员在测试过程中主观上认为测试结果是有问题的,并开出缺陷。但实际上产品设计就是应该如此表现。如果测试人员也同意如此设计是有道理的,就应取消所开缺陷,并视之为无效缺陷。
产品局限性:是指所开缺陷由于产品本身设计框架等局限性而无法修复。这样的缺陷通过改动代码是无法修复的,一般来讲最好转变为修改文档,通过文档来告诉用户这些局限性。如果既不能修改代码又不能修改文档,那么只好取消缺陷,并视之为无效缺陷。
未来功能:是指所开缺陷实际上是要求产品增加新功能。如果新功能不能在当前版本里实现,就应记录在未来版本的新功能候选名单上,并取消此缺陷且视之为无效缺陷。
不可重现:是指所开缺陷无法在相同场景中重现。有时可能由于网络,机器等问题而使测试案例无法正常运行,但重新测试很多遍也无法重现当时的问题。这种情况会建议取消缺陷,一旦同样问题再次发生,就需重开缺陷。
一般应该对无效缺陷进行分析,找出导致无效缺陷比例高的原因并提出相应的改进计划。
如图9-3所示,在18个无效缺陷里,重复缺陷占比例最高,其次是用法错误。所以就要进一步了解造成重复缺陷比例高的原因并予以改进。例如,可通过一些方法来提高测试团队之间的沟通,来有效降低重复缺陷。但有些重复缺陷是很难避免的,尤其是那些显示不同错误信息,但造成问题的代码是相同的缺陷。这些缺陷在很多测试专家眼里可以认为是有效缺陷。
用法错误的无效缺陷,在测试过程中应该尽量避免。这就要求测试人员要对测试案例有正确的理解而避免不必要的用法错误。另一方面,有些用法错误的缺陷可以转换成提高实用性的有效缺陷。
例如,小艾在安装测试时安装失败,小艾认为是安装代码的问题而报告了这个缺陷。开发人员在经过调查后发现是小艾不小心输入了错误的数据库密码而导致安装失败,就认为是用法错误而返回缺陷。小艾咨询了安装测试负责人,安装负责人认为虽然是测试人员用法错误,但从使用性上来讲,客户会遇到相同问题,产品应该能够在客户输入错误密码时提示客户,并禁止进一步安装。最终,开发人员接受了安装负责人的建议并修改了代码。而小艾所开的缺陷也成为提高使用性的有效缺陷。
2、按严重性分析缺陷
缺陷按问题的严重程度分为以下几个等级。
一级严重:是指缺陷造成整个应用或功能不工作,从而导致产品不能交付。
二级严重:是指缺陷造成功能输出结果错误。
三级严重:是指缺陷造成功能没有按预期方式实现。
四级严重:是指功能上需要加强。
在测试过程中,一级和四级严重缺陷应占比例较少,二级和三级严重缺陷比例应该占大多数。这是因为大部分一级严重缺陷在开发过程的单元测试中应该被发现和解决,而不应该流入到测试流程。
如图9-4所示,一级严重缺陷占39%,二级严重缺陷占33%,三级严重缺陷占21%,四级严重缺陷占7%。在此图中,可以发现一级严重缺陷的比例偏高。需要分析一下为什么会出现这种状况,是否有些缺陷应该在开发过程的单元测试中发现。应该把分析结果反馈给相关开发人员,并共同完善单元测试的测试范围,尽量让一级严重缺陷在早期发现并修复。
3、按功能分析缺陷
我们一般会看不同功能上发现多少缺陷。有些功能逻辑比较复杂,涉及的方面较多。这种情况所发现缺陷比例就会稍大。有些功能较简单,和其他功能没有太大交集,所发现缺陷就会相应较少。
如图9-5所示,功能2所发现缺陷占总数的41%,而功能4仅为7%。这说明功能2的复杂度相对大些,可能有必要再重新看看测试范围并增加一些测试案例。
4、按修复时间分析缺陷
一般来讲,一级严重缺陷需要开发人员一天之内解决,二级严重缺陷需要两天之内解决,三级严重缺陷要在一周内解决,四级严重缺陷应在两周内解决。
所以大部分缺陷从开始报告到最终核对并确认修复的周期应在一周内。不同测试类型缺陷修复时间是会稍微有一些差别的。例如性能测试的缺陷和迁移测试的缺陷由于测试环境较为复杂,并且较难找出造成缺陷原因,所以这两个测试类型的缺陷完成周期会相应长一些。
图9-6和图9-7分别是安装测试缺陷修复时间和性能测试缺陷修复时间数据图,从图中可看出,性能测试缺陷修复在20天以上的明显增多。这是由性能问题的复杂性决定的。依照经验,解决一个复杂的性能问题,有时候需要一个月甚至两个月的时间。所以对缺陷修复时间的分析要根据不同测试类别去进行。不同测试类别的缺陷修复数据可以用来作为今后各测试团队做项目测试计划的参考数据,例如性能测试要计划出足够的时间来核查缺陷修复。
5、按所属类别分析缺陷
理想情况下,各测试团队在测试时只发现自己所测类型的缺陷。但现实情况是所有测试类型虽然测试有先后,但也存在很大程度的时间重迭。
例如,由于性能测试的环境和数据要求很复杂,性能测试的测试成本远远大于功能测试的测试成本。所以性能测试一般会在其所需要的主要功能测试基本完成的情况下开始。但主要功能测试基本完成,并不代表此功能不存在缺陷。另外,主要功能在测试成功后,也可能由于后来的某些相关代码改动而存在回归缺陷。这就造成性能测试中不可避免地发现功能方面的问题。
通过对性能测试团队所发现缺陷的分析,可以统计出功能测试缺陷所占比例,看是否功能测试缺陷比例过高,是否严重影响了性能测试的进度,从而分析在今后的测试过程中,哪些测试流程需要提高而尽量减少性能测试中的功能缺陷。例如增强和功能团队的沟通,尽量了解性能测试中,每个测试案例里所需主要功能的进展情况等。
另外,性能测试需要安装和客户相近的测试环境,所以也会不可避免地发现安装缺陷。它的测试环境的复杂度也会帮助安装团队扩大安装测试范围。
如图9-8所示,在性能测试中,功能缺陷占大约28%。这个比例稍微偏高,会对性能测试的进度有所影响。我们在分析过程中可以着重看看哪些功能缺陷是可以通过提高流程而避免的,并制定好相应计划,在今后测试中有所改进。
6、操作系统分析缺陷
如果是Java EE的应用程序,应该不会有太多操作系统相关的测试缺陷。但由于安装程序或多或少会和操作系统的设置文件有关,所以在测试中不可避免地会发现操作系统特定问题,例如某些缺陷只在Solaris上存在,在其他操作系统上没有问题。
通过缺陷分析,可以清晰地了解操作系统特定缺陷所占比例。如果比例不大,在测试中可以把大部分测试案例都放在机器资源相对充足、便宜且操作系统相对简单的环境里测试,以减少测试人员和机器资源的消耗。
如图9-9所示,安装测试中和操作系统无关的缺陷占88%,所以大部分测试案例可在一种操作系统上进行测试。但因为其他操作系统也存在特定缺陷,所以在所有其他操作系统上,也要安排一些测试案例。
7、按数据库分析缺陷
现在绝大部分软件产品会需要数据库来存储并提取数据。不同的数据库处理数据的方式会有所不同。如果一个产品同时支持多种数据库,就可能存在同样的测试案例,在一种数据库上工作正常、但在另外数据库上出现问题的情况。
在测试过程中要尽量覆盖所有支持的数据库。如果有些功能对数据库不敏感,就只需在某一数据库上集中测试,在其他数据库上做些小测试即可。如果功能对数据库极度敏感,就要考虑不同数据库都要有足够的测试范围。
按数据库分析缺陷,可以相应看到哪些功能对数据库敏感且特定缺陷多,就需要考虑是否在此功能上增加不同数据库的测试范围。
8、按可用性分析缺陷
在测试过程中,不但要测试产品功能是否正确,还要看产品是否好用,即通过用户的使用角度来评估产品。由于它反映了用户的真实使用经验,所以可以视为一种不可或缺的可用性检验过程,例如界面是否友好、是否提供在线帮助,用户在使用错误的情况下是否显示容易理解的异常信息等。测试团队应鼓励测试人员尽可能多地发现可用性缺陷来提高产品的质量,从而使用户有非常好的产品使用经历。
例如在安装产品过程中,如果操作系统不符合产品安装要求,就应该报出错误信息,并终止安装。如果测试过程中没有报错误信息,只是在安装中途失败,这就是一个可用性缺陷。在测试过程中,一定要从客户的角度来看问题。对于任何在使用时觉得不方便,不通用且容易造成用户困惑的功能,都要想想是否是可用性缺陷,是否应该进行修订而提高其易用性。
例如在网上商店注册时,会要求用户输入很多个人信息,例如姓名、年龄、职业、住址、家庭状况等。有些是必填项,有些是自愿填的。假设在输入信息时忘记填写必填的一项,在单击“完成”按钮时,如果系统只是提示你有未填项目,并要求你重填所有信息,这对于用户来讲是非常不能忍受的。这种情况就应该开出可用性缺陷。
可用性好的产品会这样处理:系统提示你有一项没填,并把未填项标志出来方便你继续填写。其他已填好信息依旧保存在页面上。这样既方便又快捷地帮客户解决了问题,从而使用户得到非常好的使用体验。
测试过程中可用性缺陷的多少能够在一定程度上衡量测试人员的专业性和产品质量的高低。一般产品可用性测试没有专门事先写好的测试案例,更多的是依靠测试人员的测试经验和对产品的熟悉程度。如果整个测试过程中,只有很少甚至没有可用性缺陷,就要好好分析一下原因,看是否是因为测试时间紧张,测试人员只是着重测试了产品的正确性,而忽略了产品使用性的测试。
9、按照其他指标分析缺陷
缺陷分析的指标多种多样,每个团队的侧重点存在一些差别。我们在前面列举了几种分析缺陷的主要方面,除此之外,还有许多指标可以用来做缺陷分析。
例如把缺陷的创始人作为指标来分析,可以看到哪些测试人员所发现的缺陷数量最多,有效性最高。一般来讲,同样的测试类型,有经验的测试人员平均比无经验的测试人员发现缺陷多且有效性高。缺陷的拥有者也可以作为指标来分析,从中可以看到哪些开发人员在整个项目中所修复的缺陷最多。
总之,缺陷分析是项目测试时和完成后都需要重视的一项任务。它既能帮助测试人员随时调整测试范围和侧重点以防患于未然,又能很好地帮助总结经验教训,以便于今后项目的提高和发展。
9.4 学习笔记--成品测试之小艾观
小艾通过成品测试及成品测试之后的经验总结学到了很多东西:
成品测试的一个主要目的是测试最终介质和包装有无缺陷,以保证客户拿到最终产品时能顺利安装并使用我们提供的光盘(CD或DVD)或网上下载的应用程序。成品测试另外一个测试目的是保证产品在前期缺陷修复过程中没有因为代码改动而产生新问题。
成品测试阶段有其独特的测试策略和灭虫方案:
在已存在的测试案例里挑5%~10%重要案例来重新测试以保障以前的代码改动没带来新的质量问题。所被挑选的回归测试案例尽量能够涵盖程序的主要功能,以确保程序的主框架没有由于前期代码改动而产生缺陷。
尽量不要在此阶段运行新的测试案例,用于保障成品测试能在合理时间内完成(一般为2~4周)并成功交付给客户或投放市场。
由于不同操作系统平台或数据库调用的安装程序和启动的包装有可能不同,所以在测试中各测试团队要协同作战,尽可能涵盖所有系统平台和数据库,以保障客户在不同系统上的正常应用。
所有测试都应基于DVD或DVD ISO文件安装的应用程序,严禁再用测试驱动来安装应用程序并进行测试。
由于成品测试是测试的最后一个环节,且周期很短,因此就要求代码改动要特别慎重,以防引起回归问题。成品测试阶段项目组一般要每天审核所发现缺陷并做缺陷综合分析,根据分析结果制定相应灭虫策略,有些缺陷可延缓到以后修复。对于要修复的缺陷,必须要有足够的回归测试,以保证代码改动没带来新的质量问题。
成品测试之后,需要把最终结果填写到质量检测报告中并通过最终审批,产品才能最终交付客户。质量检测报告是项目中需要完成并得到审批的一个重要文件,其中包括下面几个方面:
项目特征;
产品用户体验;
性能指标;
产品试用版本计划;
质量预见性指标,包括评审指标、测试指标、项目退出指标、延缓缺陷指标、源代码分析指标。
在产品交付后,需要对项目做经验总结,同时各测试团队要对所有缺陷做最终缺陷分析,以此总结经验教训,以便在今后的项目中做出改进。不同测试类型会有不同的缺陷分析侧重点。一般包括缺陷有效性分析、缺陷严重性分析、不同功能上发现的缺陷分析、按修复时间分析、按缺陷类别分析、按操作系统或数据库分析、按可用性分析等。
缺陷分析应该贯穿整个项目测试过程,而不仅仅是在测试完成后。通过不断进行缺陷分析,来监控在开发和测试中是否存在问题和漏洞,并根据分析结果来调整测试范围和策略,防患于未然。
(连载完)
相关链接:
一个软件测试工程师的成长日记(连载一)
一个软件测试工程师的成长日记(连载二)
一个软件测试工程师的成长日记(连载三)
一个软件测试工程师的成长日记(连载四)
一个软件测试工程师的成长日记(连载五)
一个软件测试工程师的成长日记(连载六)
在实际的项目中,往往由于时间紧,测试人员不足等原因,无法做完全的测试,需要对测试工作进行取舍。一般来说,需要确定测试的重点,排出优先级,根据优先级取舍。
那么,如何确定测试的重点呢?主要从以下方面考虑:
被测功能在系统中的地位
在一个软件内部,不同功能模块的质量标准一般来说也会有差异。客户最关注的功能显然应该得到测试的重视,需要投入较多的精力对其进行验证。除此之外,对那些非核心功能、但对核心功能产生影响的模块,我们也不应该忽视,至少要保证这些模块在一般情况下能够正常运转,在遇到异常情况时能够做出令人接受的合理反应,不会导致核心功能发生超出耐受度的错误。
客户能够容忍哪些错误存在
从另一个角度看,客户对不同模块中发生的不同错误的接受程度是不一样的。某些模块不允许出现任何功能错误,但少量的不严重的界面问题可以容忍,而另一些模块偶尔出现功能错误也可以接受,但必须保证界面显示正常。某些功能必须满足长期运行的要求;而有些软件允许在运行期间重新启动,甚至可以允许有轻微的内存泄漏。
针对客户能够接受和不能接受的错误,我们可以相应地确立测试的侧重点。比如:对功能要求高于界面要求的模块,可以加强功能测试,减少界面测试用例个数或者减少界面测试用例的执行次数。
被测功能的使用频率
使用频率高的功能发生意外的可能性相对要高一些,而且,这些功能中一些小问题所造成的影响可能会随着使用次数的增多而被扩大。对于这样的模块,测试的标准不能设置得太低,特别是核心功能中使用率最高的模块,一般情况下应该重点测试。
发生异常情况的可能性
用户输入错误数据的可能性有多大,他们不太可能输入什么样的错误数据?用户操作时可能会改变通常的执行顺序吗?为当前功能提供输入数据的其他模块的出错机率高吗?当一个功能需要多个模块共同协作才能完成时,这些共同协作的模块是否都足够稳定?当前功能并发操作的可能性是否高?系统运行的相关软硬件是否安全和健壮?有很多的因素我们需要考虑。
与不太可能出现的错误情况相关的测试用例,我们是否可以试着将其执行优先级设置低一些?例如:在多种错误输入数据中,优先尝试最有可能出现的错误数据;如果使用者一般不会对同一数据进行操作,那么对并发操作可以暂时不进行测试。
错误所造成的影响
不同模块出现的错误造成的影响是不同的,这些影响可能是数据丢失、系统的异常退出等等。例如:某个操作数据库的模块出现异常后,有可能对数据库造成死锁,阻碍其他模块的正常运行。对这样的模块,需要进行仔细的验证。
被测功能是否是一个错误易发的功能
在执行测试的过程中,我们会发现某些模块在几轮测试中总是比其他模块出现的错误多。这些模块应该引起测试的注意,因为它们在以后的测试中仍然可能会出现很多错误,我们不能减少对它们的测试,如果这些模块属于核心功能或者是用户常用的功能,可能还需要增加测试用例以更多地发现隐藏缺陷。对于那些错误少且错误数量已呈收敛趋势的模块,如果其本身功能未发生改变或者其他模块的修改对其不造成影响,我们不妨适当减少对这些模块的测试次数,例如:在后面的几轮回归测试中不对其进行测试,直至最后的回归测试。
在同一模块中也存在类似问题。如果一个模块在前几轮的测试中都没有发现存在某些方面的错误,为检查这些错误而设计的测试用例在后面几轮回归测试中可以减少执行次数。
测试是否足够充分和合理与软件交付时间和软件质量直接相关,这不仅仅是测试组的责任。对于一个项目来说,测试工作的目的不是为了寻找错误而寻找错误,或者发现软件的所有错误,而是在允许的人力条件下,保障项目组在规定时间内交付一个客户能够接受的软件产品。
版权声明:本文出自 shiningredstar 的51Testing软件测试博客:http://www.51testing.com/?7622
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。
9.2 黎明前的黑暗--漏网之虫
坐在实验室的机器前,小艾用DVD光碟按照安装指示文档安装好产品,就开始运行所分配的功能测试案例。因为所分配给的测试案例都是小艾在测试第一和第二阶段运行过的案例,小艾感觉执行起来轻车熟路。一上午就完成了快一半,小艾暗暗松口气,为自己的进度感到高兴。
9.2.1 老案例生新虫子
中午吃过饭之后,小艾又急忙回到实验室运行测试案例。接近下午3点时,小艾在运行一个案例时发现了一个较严重的问题。小艾记得自己两周前在功能测试第二阶段运行过这个案例,当时没有发现任何问题。小艾怕自己记错,赶忙到数据库里查了一下这个测试案例运行的历史,发现最后一次成功运行的确是在两周前。
小艾于是怀疑最近两周这个功能有新的代码改动,为了进一步确定,他就又查了一下和这个功能有关的最近两周的缺陷修改历史,发现一周前开发团队的姚圳曾由于修复和这个功能有关的性能缺陷而修改过相关代码。由此,小艾基本肯定他新发现的功能问题是由于最近的代码改动引起的。于是他在代码管理系统里开了一个缺陷记录,标明是回归问题,并把自己的一些初步调查结果也注明在记录里,以方便开发人员参考。
考虑到问题比较严重,时间又很紧迫,小艾立即给姚圳打了个电话,把情况说了一下,并告诉姚圳可以参考他所开的缺陷记录来得到案例步骤及错误信息等详细情况。
姚圳听后说:“好的,谢谢你及时通知我,我会立即看一下。这个问题听起来很严重,而且对客户影响很大,需要马上解决。我会争取今天找到问题原因和解决办法。不知你明天能否早一点到公司,我需要你帮忙试一下代码补丁。由于现在是成品测试阶段,项目组要求所有正式源代码改动都需要事先在测试环境里通过案例测试和相关回归案例测试,测试完成后才能得到项目经理授权集成到下一个成品测试候选驱动里。”
第二天早晨小艾早早来到办公室,就看到姚圳发来的电子邮件。从电子邮件时间上看,姚圳一定为这个问题忙到了半夜。小艾不敢耽误,马上开始安装补丁并进行相应案例测试。为了保险起见,小艾又把和这个功能有关的一些主要案例运行了一遍,以防止又产生新的回归问题。
接近中午时,小艾终于顺利完成了补丁测试,他于是兴冲冲地跑去通知了姚圳。
姚圳松了一口气,笑着对小艾说:“太好了,我们在昨天下午4点的成品测试缺陷评判例会上已讨论过你发现的这个问题及它对客户的影响,项目组让我们两天内尽快解决这个缺陷。这下好了,我们提前一天完成了任务。我会参加今天下午4点的成品测试缺陷评判例会并汇报一下最新情况。如果不出意外,这个问题的源代码改动应集成在明天的成品测试候选驱动里。”
小艾很不好意思地说:“呵呵,我可知道你昨天为了解决这个问题熬到快半夜1点,你才是劳苦功高呢。姚圳,你是公司的老员工,参加了好多项目开发工作。你能告诉我成品测试缺陷评判例会主要有哪些内容吗?”
姚圳拍了拍小艾的肩膀说:“你可问对人了! 我参加了好多次这样的例会,的确有一些了解。这个例会主要用来及时分析所发现的缺陷并根据缺陷影响给出解决方案。一般项目经理都会要求各开发团队代表、各测试团队代表、客户支持代表甚至产品补丁版本项目经理一起参加。在会上项目经理通过听取各方意见来决定缺陷的最终解决方案。”
小艾很疑惑地问道:“难道我们不应该通过及时修订代码,在把产品交付客户之前灭掉所有发现的虫子吗?”
姚圳回答道:“你说的是理想情况。实际来讲,成品测试阶段时间有限,所有测试都已基本接近尾声。如果这时改动大量代码,又没有足够时间进行必要回归测试,就很容易造成回归缺陷不被发现。这样反而会给客户造成更大损失。所以成品测试阶段有和测试前期阶段不同的灭虫策略。我们一般需要在此期间对发现的虫子进行综合分析,并根据对客户的影响和其紧迫性提出相应解决方案。”
小艾很期盼地问道:“根据这么多年的经验,你能告诉我一般都对虫子做哪些分析,相应地都有哪些解决方案吗?”
9.2.2 艰难抉择--漏网之虫综合分析及灭虫策略
在中午吃饭时间里,姚圳给小艾详细解说了成品测试阶段缺陷综合分析及相应灭虫策略。
缺陷综合分析要点:
缺陷是如何发现的。如果不是回归问题,为什么在测试前期没有发现,是否存在其他潜在的测试漏洞。
通过对虫子漏网原因的分析,能够更清晰地明白是否存在严重测试漏洞。修复此缺陷后是否需要增加回归测试范围以防再出现同样功能的回归问题。
有几种方法可以解决缺陷,每种方法的优缺点及客户接受程度。
例如某些缺陷是可通过多种方法解决的,但每种方法对代码架构的影响、对测试成本的影响和对客户的影响都不尽相同。需要平衡时间、成本及客户接受程度等要素来决定此时最佳解决方案。
缺陷修改对当前代码架构的影响,会影响到哪些测试团队。
例如有些代码改动可能需要功能测试团队,性能测试团队和安装测试团队重新运行一些测试案例。
受影响的测试团队需要多少时间和人力来完成由于代码修改而必须运行的测试案例包括回归测试案例。
通过测试成本计算,能够清晰地知道是否能有足够时间和人力在产品交付时间之前完成缺陷修复。
如果此缺陷不在当前版本里修改,会对客户和客户技术支持团队造成什么影响。
客户影响是非常重要的一个要素。有些缺陷被叫做“禁止交付”缺陷,顾名思义就是如果产品存在这些缺陷,则产品不能交付给客户。因此所有“禁止交付”缺陷一定要在产品交付前有解决方案。
另外,客户技术支持团队需要衡量一下,如果某缺陷不在当前版本修复,在当前产品版本推向市场后如果客户遇到相同问题,客户技术支持团队会需要额外付出多少人力资源来和客户沟通并解决客户问题。
客户对此产品缺陷的最大容忍时间大约多久。
通过分析客户对修复此缺陷的紧迫性来决定是在当前产品版本修复还是将缺陷修复推延到以后的产品新版本包括补丁版本、小版本或产品下一升级版本。
根据缺陷分析结果,一般会有以下解决方案:
在当前产品版本里修改缺陷,并按时交付客户。
例如:某些缺陷对客户影响大且缺陷修改对代码构架影响较小,测试团队能按期完成测试任务。
在成品测试阶段,所有缺陷修改必须经过项目经理同意并通过案例测试和回归测试后才能集成到下一个成品测试候选驱动上。
在当前产品版本里不修订缺陷,尽快在产品补丁版本或小版本里修改缺陷,并尽快交付客户。
例如一些产品功能客户在产品上线初期不会用到,和此功能有关的一些缺陷可以在随后发布的补丁版本里修复。
在当前产品版本里不修复缺陷,在下一个产品升级版本里修改缺陷。
例如有些缺陷对客户业务影响不是很大,只是在应用上需要一些改进而使客户应用起来更方便,对于此类缺陷,如果是在测试前期当然是尽可能修复。但在测试后期,尤其是成品测试阶段,就尽量不要因为此类缺陷改代码而引起不必要的回归问题。
在当前产品版本里修改缺陷,但需要推迟交付客户。
这种情况很少见。原因可能是前期测试存在重大漏洞,而存在的缺陷是客户不能接受的,但产品开发团队又无法在原定交付时间完成缺陷修复和相关测试。当然这种情况是每个产品项目都要想方设法避免的。
注意:如果缺陷修复需要推延到以后的产品新版本包括补丁版本、小版本或产品下一升级版本,除了需要得到开发团队、测试团队和项目经理的同意外,还需要得到客户技术支持团队的同意和支持,以便客户遇到相同问题时,可以和客户沟通。如果对此问题有临时解决方案,也需要第一时间通知客户支持团队以便在客户需要时提供给客户。
小艾在姚圳的详尽介绍中受益匪浅,他开始考虑或许这些缺陷综合分析方法不只在成品测试阶段需要,也可借鉴到整个测试阶段,尤其是测试后期。
9.3 金蛋闪亮登场
下午的测试进行得非常顺利,小艾在3点时就完成了所有案例测试和清单列表的检测,并把结果报告发给凯文。报告中也详细说明了缺陷产生的原因和缺陷修复进度,以及对姚圳所提供代码补丁的测试结果。
9.3.1 成品测试胜利退出
5点多,凯文找到小艾说:“你报告的那个缺陷项目组已决定会在今夜的驱动里修复。明天早晨10点左右你应该就能拿到新的驱动。需要你在新驱动上重新运行和这个缺陷有关的一些案例并确保没有产生新的回归问题。”
小艾问道:“这会是最后一个成品测试候选驱动吗?”
凯文摇了摇头说:“很遗憾,不是最后一个。安装测试团队在卸载产品案例中发现了一个比较严重的问题,开发团队正在研究解决方案,目前来看代码改动无论如何也进不了今天晚上的驱动。最好情况是明天让安装测试团队测试一下代码补丁,确保没问题了再进下一个成品测试候选驱动。另外迁移测试团队的测试案例明天才能全部测试完成,现在不知是否会有新的缺陷产生。”
第二天,小艾按照所定计划完成了对缺陷修复相关案例的测试,再没有发现新的问题。小艾稍稍松了口气。
由于其他测试团队在新驱动里又发现了些问题,需要多个系统环境进行问题调查,小艾在接下来的几天里,被找去帮忙准备测试环境。凯文穿梭在不同团队之间协调人员和机器资源以加速整体测试进度,忙得不可开交。
所有人都忙而有序地工作着,等待着最后的胜利。
终于,凯文发出电子邮件给所有人员,计划将第四个成品测试候选驱动拟定为最终成品候选驱动,要求各测试团队按照计划对最后成品测试驱动进行最后一轮测试。
又经过两天紧张的忙碌,所有测试最终胜利完成,所有测试团队包括性能测试团队都相继发出电子邮件正式宣布测试完成,成品测试胜利退出。
凯文在接到成品测试胜利退出的喜讯之后,随即宣布确定第四个成品测试候选驱动即为最终成品驱动,并告知大家质量检查报告也刚已通过最终审批。按计划明天将最终ISO文件交付给生产商制造物理光碟和供网上下载的电子光碟。
整个办公室充盈着喜悦的气氛,经过近一年的努力,终于结出了胜利的果实,捧出了沉甸甸的金蛋,小艾由衷地为自己和团队感到骄傲和自豪。高兴之余,小艾对凯文信中提到的质量检测报告有些迷惑,于是他就去找凯文请教。
凯文一见到小艾,就拍着他的肩膀笑着说:“你在这个项目中成长了很多,表现不错。下一个项目你就是老员工,不再是菜鸟啦!”
小艾很不好意思地说:“要学的东西太多了,我也就刚入门。接触的事情越多,觉得要学习的东西就越多。这不又来向你请教了。”
凯文说:“你之所以能够成长很快,就是因为你有很好的求知欲。我很高兴能帮到你,有什么问题尽管说。”
小艾于是问道:“在你的邮件里提到的质量检测报告是怎么回事?我在测试阶段并没有接触到,你能给我简单介绍一下报告内容吗?”
凯文于是给小艾做了详尽的介绍,并把一些资料发给小艾供他参考和学习。
9.3.2 质量检测报告之大观
小艾认真阅读了相关材料,对质量检测报告有了很深的了解。
质量检测报告是项目中需要完成并得到审批的一个重要文件。在项目初期,项目经理需要和各团队负责人共同制定产品质量检测计划,其中大致包括:
1、项目特征
其中包括产品交付日期、项目大致介绍、项目大约所需人力物力数据、项目管理所需的几个关键日期、已知或潜在的开源产品介绍、开发流程特征等。
2、产品用户体验
需要给所开发产品的可用性、可靠性、安全性、集成性、维护性等方面制定一些具体指标,以保证用户在使用该产品时有良好的用户体验。
3、性能指标
需要制定一些性能方面的指标,客户可根据这些数据来配置硬件设施以期有效地应用产品,避免超负载、运行过慢等有害现象。
4、产品试用版本计划
需要指明产品是否有产品试用版本计划,如果有此计划,需要列明试用版本交付日期(一般要早于产品正式交付日期)和潜在试用客户名单。最后还需列明期望客户在哪些方面(例如可用性、可靠性、功能性、维护性、安装性等方面)给予反馈信息以促进产品的改进和提高。当然在产品正式交付前,还应有个客户试用版满意度调查,以了解客户对产品的功能和质量的总体看法,从客户反馈方面看产品是否达到交付标准。
5、质量预见性指标
这项指标是产品质量保障的重要监测指标。通过这些指标的制定,可以对开发和测试环节的流程,方法及范围起到有效的监督作用。主要包括:
评审指标:这项指标会通过判定相关人员是否评审了产品构架方案、设计方案、测试架构、测试方案、测试案例及程序源代码来进行质量把关。它会对每项评审列出详细评审方法。评审指标非常重要,通过专家一起评审,能够有效杜绝严重设计错误和测试漏洞。
测试指标:这项指标会通过判定测试是否包括功能测试、全球化测试、性能测试、系统测试及回归测试来进行质量把关。
指标还包括缺陷发现计划进度和实际进度的比较,误差越小越好,最好小于某指定百分比(例如10%),说明测试计划和实际相吻合,产品质量危险系数小。否则需要进行误差分析,看是否存有潜在的问题。
如图9-1所示,实际和计划进度误差在上下10%之内。可以说测试基本是按计划进行的,没有太多出入。后期缺陷发现率显著下降最后趋于零,说明产品已趋于稳定,可以交付使用。
测试指标还包括各测试类别测试案例尝试执行和测试案例成功完成的百分比。在产品质量检测报告里需要明确指出在测试计划里是否所有测试案例都能100%尝试执行,也需要明确预期在交付产品时各测试类别能最终成功完成多少测试案例。
一般情况下,如果交付产品时缺陷修复在95%以上,所有测试案例成功率在95%以上,可以认为产品质量是有保障的,存在问题的风险系数比较低。如果交付产品时各测试类别达不到90%的测试案例成功率,这个产品的质量就会有较大隐患,以后出问题的风险比较高。
项目退出指标:在这项指标里会要求在交付产品里,所允诺的功能都完成了开发和测试。如果是升级版本,还会要求没有回归问题产生,即老版本中的功能在新版本中依然正常工作。
延缓缺陷指标:我们在前面提到过(请参考9.2.2节),出于时间和安全性考虑,某些缺陷修复需要推延到以后的产品新版本包括补丁版本、小版本或产品下一升级版本。在延缓缺陷指标里一般会要求交付产品时,这些延缓修复缺陷不能超过总体发现缺陷的一定百分比(例如10%),从而对产品所知缺陷率有总体控制,保证产品质量。在这项指标里一般也会硬性规定不能延缓修复任何严重缺陷。
源代码分析指标:这项指标会评测源代码是否利用一些工具进行了静态代码分析、架构分析、代码测试覆盖度分析,用于从侧面判定产品质量是否有保障。
质量检测计划报告通过审批后,所列项目特征和指标就不能随便改了。如需改动,需要重新审批。
在项目测试完成后,需要把最终结果填写到报告中通过最终审批,拿到质量检测合格证书,才能交付产品。最终审批主要是看以下几个方面:
项目最终是否和计划的项目特征相符,是否按照计划进行开发流程。
产品用户体验的指标诸如可用性、可靠性、安全性、集成性、可维护性等方面是否达到要求。
所定性能指标是否能达到计划的标准。
产品试用版本的客户满意度调查结果是否达到交付标准。
是否按照计划评审了产品构架方案、设计方案、测试架构、测试方案、测试案例及程序源代码。
缺陷发现计划进度和实际进度误差是否小于指定百分比(例如10%)。
各测试类别测试案例是否100%尝试执行,测试案例成功率是否能达到指定百分比(例如95%)。
所允诺的功能是否都完成了开发和测试。如果是升级版本,是否没有回归问题产生。
延缓修复缺陷是否小于总体发现缺陷的指定百分比(例如10%),而且无严重缺陷延缓修复。
9.3.3 趁热打铁总结经验教训
产品顺利交付了,各个团队都在组织讨论和总结经验教训。项目经理也发出产品调查表让大家填写,希望大家在评定产品质量如何的同时,进一步总结在开发和测试过程中好的经验和需要改进的方面,鼓励大家提出如何改进的建议以便在将来的项目中进行改善,从而使产品质量得到持续的提高。
产品调查表包括下列几个问题。
请选择你在项目中的角色:
(1)产品架构师
(2)产品开发人员
(3)文档开发人员
(4)测试人员
(5)其他
请评估项目产品质量如何:(分为1级到5级,其中1级为最差,5级为最好)
( )5 ( )4 ( )3 ( )2 ( )1
请列举项目中你认为产品质量最好的部分:
请列举项目中你认为需要提高的部分:
请列举项目中你认为应该在将来的项目中继续执行的最重要的经验(包括影响力,相关团队,以及如何在将来的项目中执行):
请列举项目中你认为应该在将来的项目中改进的最重要的部分(包括影响力,相关团队,潜在的问题或者原因,改进的建议):
请列举你是否有其他的建议:
小艾根据自己测试的部分填写了自己对产品不同功能的意见和建议。并认真回顾了一下在整个项目中的所有测试历程,给团队和项目组提出了如下反馈:
应该在将来的项目中继续执行的最重要的经验:
(1)各团队之间总体有很好的沟通,有问题能够很快找到相关人员解决。
(2)测试计划和实际基本相符,开发及测试都能按计划时间完成。
(3)各测试类型团队之间没有壁垒,能够很快互相调动人力物力互相支持,以保障测试整体顺利按期完成。比如,功能测试人员帮助安装测试等。
应该在将来的项目中改进的最重要的部分:
产品功能上存在设计变动时,开发团队需要和测试团队提前沟通。测试团队需要根据新的设计来变动或添加测试案例。否则,测试团队会根据老的设计而开出无效缺陷,不但浪费了测试人员和开发人员的时间,还容易产生测试漏洞。
在产品测试阶段,任何人有需要安装产品时,也一定要严格按照安装文档来安装,如果发现文档里步骤不正确,要报告问题并要求相关团队修改文档。因为安装测试需要涵盖的范围太广,安装测试团队不可能涵盖所有情况。其他人可在力所能及的情况下,帮助安装团队发现问题。
项目组在收集到所有反馈后,会召开会议和各团队代表一起逐条讨论。对于有效反馈需要相关团队制定改进计划以便在今后的项目里实施。这些反馈里,既包括开发和测试流程的改进建议,也有对产品设计和所用开发及测试工具的改进建议。总之,给大家一个平台可以让所有人畅所欲言,总结经验教训,并以此作为参考来更好地完善今后的项目计划和实施。
(未完待续)
相关链接:
一个软件测试工程师的成长日记(连载一)
一个软件测试工程师的成长日记(连载二)
一个软件测试工程师的成长日记(连载三)
一个软件测试工程师的成长日记(连载四)
一个软件测试工程师的成长日记(连载五)
关于测试计划和测试方案的区别,这里主要从编写目的、定义和层次、编写时间和依据、软件过程、文档内容这五方面来说明,具体内容如下:
一、编写目的
制定测试计划目的:按照所制定的测试计划可以有效的计划、执行、跟踪、组织和管理测试项目。具体从一下三方面来说:
1、领导能够根据测试计划做宏观调控,进行相应资源配置等;
2、测试人员能够了解整个项目测试情况及项目测试不同阶段所要进行的工作等;
3、便于其他人员了解测试人员的工作内容,进行相关配合工作;
设计测试方案目的:软件测试方案的作用非常类似于产品设计说明书(软件概要设计和软件详细设计),开发工程师根据产品功能需求和设计说明来编码实现功能,而测试工程师需要基于产品功能需求和测试方案来设计和执行测试用例。测试方案是从测试的角度去分析或者说分解需求,在方向上明确要怎么测,分析结果就是测试点和测试方法。
二、定义和层次
测试计划是组织管理层面的文件,从组织管理的角度对一次测试活动进行规划。它是对测试全过程的组织、资源、原则等进行规定和约束,并制订测试全过程各个阶段的任务以及时间进度安排,提出对各项任务的评估、风险分析和需求管理。测试计划要能从宏观上反映项目的测试任务、测试阶段、资源需求等,它只是测试的一个框架,所以不一定要太过详细。测试计划的内容会因项目的级别、项目的大小、测试级别的不同而不同,所以它可以是一本书那么多,也可以是几张纸那么少,但是一份测试计划应该包括项目简介、测试环境、测试策略、风险分析、人员安排、资源分配等内容。
测试方案是技术层面的文档,从技术的角度对一次测试活动进行规划工具的设计、测试用例的设计、测试数据的设计。它是描述需要测试的特性、测试的方法、测试环境的规划、测试工具的设计和选择、测试用例的设计方法、测试代码的设计方案。
三、编写时间和依据
因为测试流程是按照测试计划阶段—>测试设计阶段—>测试实现阶段—>测试执行阶段来进行的,前一阶段的输出是后一阶段的输入,清楚了他们分别是哪个阶段的产物就知道他们主要的区别了。
测试计划阶段:测试计划是测试阶段中的第一个阶段,首先将测试作为一个项目来看,应该有一个计划。测试小组组长或测试负责人或具有丰富经验的测试人员就要依据《项目计划》开始编写《测试计划》,其中包括人员,软件硬件资源,测试点,进度安排和风险识别等内容。原则上测试计划的有些内容在需求分析阶段就可以开始编写了,在需求分析形成的《需求规格说明书》通过评审形成基线后完成测试计划。但是对于开发过程不是很清晰和稳定的项目,测试计划也可以在系统设计完成后开始编写。《测试计划》编写完成后需要进行评审。
测试设计阶段:《测试方案》一般由经验丰富的测试人员设计,测试方案依据《需求规格说明书》和《概要设计说明书》进行设计。其中包括需求点简介,测试思路和详细测试方法等内容。《测试方案》编写完成后也需要进行评审。
四、软件过程
测试计划软件过程:项目计划评审通过—>组建测试小组—>评估测试风险—>制定测试计划—>测试计划评审通过—>测试计划维护—>最后在测试结果的评审中,必须要严格验证计划和实际的执行是不是有偏差,体现在最终报告的内容是否和测试的计划保持一致。
项目开始后,由于测试情况的变化,如需求更改导致测试进度的调整在两周或两周以上、测试资源需求的改变(人员、硬件、软件等)、新技术的引入、新风险的引入、开发过程的改变、交付时间的改变等,可能导致测试计划文档变化。如果发生变更,则由测试组长修改,项目组相关人员评审,评审通过后更新测试计划。
测试方案软件过程:测试计划评审通过—>设计测试方案—>测试方案评审通过—>依据测试方案设计测试用例—>测试用例评审通过—>依据测试方案搭建测试环境。
五、文档内容
测试计划和测试方案的本质区别是内容不同。
测试计划的核心内容:
1、进行测试任务划分;
2、进行测试工作量估计;
3、人员资源和资源分配;
4、明确任务的时间和进度安排;
5、风险估计和应急计划;
6、测试失败/通过的标准;
测试方案的主要内容:
1、测试策略选取,明确策略;测试策略就是如何用最少的资源满足测试质量的要求,既高效、低成本、较高质量的完成测试。
2、测试子项细分,细化测试特性形成测试子项;将测试计划中描述的方法进行细化,包括要采用的具体测试技术。
3、测试用例的规划;
4、测试环境的规划;
5、自动化测试框架的设计;
6、测试工具的设计和选择;
总而言之,测试方案需要在测试计划指导下进行,测试计划提出了“做什么”,测试方案明确了“怎么做”,方案是对计划的进一步细化和明确。两者既有联系又有区别,概念总归是概念,根据软件项目规格大小以及实际应用环境,测试人员应该具体问题具体分析。
版权声明:本文出自 545168150 的51Testing软件测试博客:http://www.51testing.com/?612044
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。
<不能成为专业软件测试人员的10大理由>终于在两个夜晚苦战到12点多翻译完了,2,3年不接触英文还真是很生硬,可能大家一看就知道是Chinese English,哈哈!只能请阅者委屈一下了,以后我也要多多学习英文啦~
原文作者是之前负责惠普公司QC的一名测试前辈,无意中看到他的文章,有些我觉得还是很在点子上的。所以就当一边学习英文,一边总结测试相关的就出来这篇译文了。
在译文出来之后,有同行伙伴提出了一些疑问,在这里我也结合我的工作实际阐述一下。
1、文章中第二点,深圳的一位网友就提出了:在中国90%以上的中国IT企业很难做到让测试人员在开发早期甚至需求早期就介入。
我不太确定他说的90%是否有数据支持,至少我所认识的很多同行都会在需求阶段让测试人员介入,如果还不是这样,我想测试人员是时候做些什么了吧??绝不能坐以待毙.我待过2家互联网公司,说说我的经历。一家是创业型公司,一家是中型公司,当时我们是如何做的呢?创业型公司,或许很多这样的公司,都没有较为成熟的文档化和流程,以快为先,唯快不破。没有专职的项目经理,甚至产品经理都没有,我们的CEO,CTO就是产品经理,甚至我们每个人都可以为产品设计贡献思路。老板们的想法已经成型了,很多时候在脑子里,没有文档化,然后开需求宣讲会议,因为人不多,开发测试都会参加,会议上也会有一些讨论,这是大改,还有小改,可能就发邮件给大家,邮件也算是文档吧。大多数时候大家很难在会议上就发现需求的全部漏洞,但是基于对系统的理解,有时候测试人员的思路也很活跃,“可以...不可以...如果...如果不...”类似使用场景的思路联想到的问题可能起到作用。但是不去参加这个会议,可能就只能到了代码写完提交给测试了,这个时候最大的问题就是,如果开发人员理解的有偏差,测试人员如何保证产品的质量呢?只有保证测试的需求与业务需求是一致的,才能真正的说明我们测试的是一款正确的产品。
其实如果不去参加那个宣讲会议,就是那位网友说的情况了。在我看来,在没有项目流程的公司里,测试人员要更加主动,主动承担一部分项目管理的工作。如果没有文档,可以主动申请加入到需求宣讲中去。其实参与到宣讲中,至少还有一个好处,可以知道为什么这么改,有助于我们更加理解业务的初衷。如果是邮件发出来的,可能就没有这么多来龙去脉。
上面说的是业务需求,其实对于开发设计的会议,我当时也是非常乐意去参加的,你会知道他们的设计思路是什么,大致算法如何设计,有哪些异常处理,是否有异常报警机制等等。没错,我能想到的一些use case也会提出来,让他们开发的时候考虑到。这样子,我能更懂产品,测试思路也更宽阔,而且让开发理解我们测试人的思路,如果他们也懂一些测试思路,很多问题在开发设计阶段就可以规避了,这也是尽早测试的意义所在。
再说第二家公司也就是现在这里,流程稍微正规一些,不过也是一步一步建立起来的,测试人员也参与到流程改进中去。有专职的项目经理和产品经理,需求是产品经理事先设计好的,只不过设计的时候可能会阅读原有的设计文档或咨询一下之前负责的开发或测试原来的业务逻辑,这也是为了取其精华去其糟粕,这是需求设计完成前测试人员唯一介入的;当需求设计完成后会发给项目组成员,组织宣讲,会议上可以提出相关疑问,产品经理会记录下来再进行确认或重新设计。之后需求设计freeze,如果不是特别大的问题,其他需求变更可以考虑延后处理,对于严重需求漏洞就需要及时变更,越往后成本越高.之后开发测试人员会依照新的文档开始工作,但是在测试设计用例或开发代码设计时经过更深入业务理解之后可能又会发现需求的一些问题,会集中反馈出来,产品经理一样会酌情考虑是否延后处理.后面的阶段就是进行用例评审,组织测试等等了.总体来看流程比之前创业型公司顺了很多,至少测试可以较早的介入.当然,测试人员参与到流程改进中也是一大保证.至少我的经历来看,项目延期的几大杀手就是需求变更,无流程和糟糕的项目计划.
2、对于第三点中的情况,我想作者的意图也只是想要表达场景法设计用例的重要性,而且场景法设计用例的确是贯彻软件测试的始末.如深圳的那位朋友所说,没有一款产品是需要覆盖100%的,我们的策略都是一定要覆盖重要核心的业务,次要的备选流业务可以通过产品,开发及测试三方评审哪些需要覆盖哪些不需要覆盖,以得出测试的范畴,因为即使测试出了bug,也可能不修复,我想不被修复的bug是没有意义的.而且评审过的测试范围即使某天出现遗漏我们也有说法.
3、对于第一点中谈的代码能力.我个人意见是:这项技能是锦上添花,并不需要每个测试人员都需要具备.但是具备了就可以参与到项目的code review中去,在提测前期就可以发现很多问题,而且具有代码能力的测试人员可能更懂得如何更有效的去测试。
据我对功能逻辑性bug的分析,记住是功能逻辑性的不包括其他类型诸如UIUE上的。主要有3类:
1)大多数bug是很简单的代码错误,如果一经过大家的评审,就能发现出来;
2)一部分是业务理解错误,写的代码不符合业务需求,代码走读时也可以发现部分问题,但是不能发现全部,代码走读也可能只是对核心业务代码或接口部分进行的评审,而系统层面的需要在系统测试阶段才能发现。如果在前期保证产品,开发和测试三方对需求理解的一致性,就可以减少很多这样的bug,不是吗?
3)还有一小部分可能真的是比较难处理的bug,难复现,难调试。这部分东东,测试人员也很难评审出来。
4、最后我再补充一条:能够将自动化和手工测试很好结合起来开展工作的也是一大挑战。
我相信在很多公司,专业做自动化测试的团队对业务理解不够深刻,他们很多时候都是在研究新的技术完善测试框架,或者按照手工测试用例的优先级编写脚本,然后只是让自动化daily run。而且他们不一定知道测试哪个需求时需要自动化配合做回归测试,或者哪些内容可以提前把关键流程的用例事先实现自动化,等提测之后用来自动化smoke,哪些需求变更了又需要更新自动化。如果通过双方测试人员沟通,这种沟通的成本我觉得也不少。熟练地掌握手工测试技能并且能够自动化实现,在项目测试中很好的配合,以节省回归测试时间,这是一个挑战也是一个趋势。
相关链接:
不能成为专业软件测试人员的10大理由
字体: 小 中 大 | 上一篇 下一篇 | 打印 | 我要投稿 | 推荐标签: 软件测试 QC 测试工具
需求管理(REQM,Requirements Management)属于成熟度2 级(受管理级)的过程域,是其他许多过程域实施的前提。对于暂未实施CMMI 的企业,同样也可以借鉴CMMI 的原则,实施和优化需求管理。
许多IT 企业都有过需求失控的痛苦经历,我们不难体会,没有好的需求管理会给我们带来什么:
● 需求以失控的状态进入软件过程,从源头上失去了项目的质量保证;
● 需求范围界定不清,使项目缺乏计划性,导致成本、研制周期失控;
● 需求变更失控,使组织处于被动反应式的环境中,项目组成为救火队;
● 需求管理不当,导致项目延期、士气低落,增加了项目的失败风险;
● ……
为了避免上述情况的出现,CMMI 对需求管理提出了明确的目的:一是管理项目的产品和产品构件的需求;二是标识哪些需求与项目计划及工作产品之间不
一致。通过适当的步骤,确保需求在项目的各个层面上动态地保持一致,一旦出现不一致,则启动相关的处理过程域,使其调整到一致。
需求管理的工具包括:
1、需求及相关文档管理的工具;
2、流程审批的流转电子化;
3、溯源性矩阵的维护工具。
其中最大的难点是需求溯源性矩阵的维护工具,对此我们作重点分析。
需求溯源包括的三个方面,可看作是三个子矩阵,每个子矩阵对某个方面都具有双向溯源性。
● 需求向低层分解的双向溯源矩阵
● 需求沿生命周期纵向产品溯源矩阵
● 需求的水平溯源矩阵(跨系统功能间)
综上所述,需求管理要求建立和维护需求双向溯源表,而双向溯源表的关联关系非常复杂,因此:
1、必须借助工具进行管理。对小的项目,可以用Excel 等简单工具进行管理,但对大型项目或组织级的需求管理,则应购买或自行开发专门的需求管理工具。
2、必须建立一套编码体系,以便进行标识和检索。
3、需求管理工具可以与配置管理工具同时考虑,即综合设计成一个管理系统。
一、国外需求管理工具
Rational RequisitePro
IBM Rational RequisitePro 解决方案是一种需求和用例管理工具,能够帮助项目团队改进项目目标的沟通,增强协作开发,降低项目风险,以及在部署前提高应用程序的质量。通过与Microsoft? Word 的高级集成方式,为需求的定义和组织提供熟悉的环境。提供数据库与Word 文档的实时同步能力,为需求的组织、集成和分析提供方便。支持需求详细属性的定制和过滤,以最大化各个需求的信息价值。提供了详细的可跟踪性视图,通过这些视图可以显示需求间的父子关系,以及需求之间的相互影响关系。通过导出的XML 格式的项目基线,可以比较项目间的差异。可以与IBM Software Development Platform 中的许多工具进行集成,以改善需求的可访问性和沟通。
网址:http://www-306.ibm.com/software/rational/
Telelogic DOORS
Telelogic DOORSreg; Enterprise Requirements Suite (DOORS/ERS) 是基于整个公司的需求管理系统,用来捕捉、链接、跟踪、分析及管理信息,以确保项目与特定的需求及标准保持一致。DOORS/ERS 使用清晰的沟通来降低失败的风险,这使通过通用的需求库来实现更高生产率的建设性的协作成为可能,并且为根据特定的需求定义的可交付物提供可视化的验证方法,从而达到质量标准。Telelogic DOORS 企业需求管理套件(DOORS/ERS)是仅有的面向管理者、开发者与最终用户及整个生命周期的综合需求管理套件。不同于那些只能通过一种方式工作的解决方案,DOORS/ERS 赋予你多种工具与方法对需求进行管理,可以灵活地融合到公司的管理过程中。以世界著名的需求管理工具DOORS 为基础,DOORS/ERS 使得整个企业能够有效地沟通从而减少失败的风险。DOORS/ERS 通过统一的需求知识库,提供对结果是否满足需求的可视化验证,从而达到质量目标,并能够进行结构化的协同作业使生产率得到提高
网址:http://www.telelogic.com
Borland CaliberRM
Borland CaliberRM 是一个基于Web 和用于协作的需求定义和管理工具,可以帮助分布式的开发团队平滑协作,从而加速交付应用系统。CaliberRM 辅助团队成员沟通,减少错误和提升项目质量。CaliberRM 有助于更好地理解和控制项目,是Borland 生命周期管理技术暨Borland Suite 中用于定义和设计工作的关键内容,能够帮助团队领先于竞争对手。CaliberRM 提供集中的存储库,能够帮助团队在早期及时澄清项目的需求,当全体成员都能够保持同步,工作的内容很容易具有明确的重点。此外,CaliberRM 和领先的对象建模工具、软件配置管理工具、项目规划工具、分析设计工具以及测试管理工具良好地集成。这种有效的集成有助于更好地理解需求变更对项目规模、预算和进度的影响。
网址:http://www.borland.com
二、国内需求管理工具
统御需求管理软件(oKit-req)
oKit-req 是一款基于Web 的需求管理工具,它是统御项目管理系统(oKit)的一个关键功能,也可以作为独立软件使用。oKit-req 具备以下主要功能:
(一) 支持对多个项目需求的管理;
(二) 版本化、层次化、条目化管理需求;
(三) 方便的建立需求跟踪矩阵;
(四) 进行变更影响分析和覆盖面分析;
(五) 输出成WORD 文档;
(六) 离线交换和合并文档;
(七) 全程跟踪需求变化历史,支持附件和图文表。
网址:www.kingrein.com
四者的比较
令人烦恼的需求变更
在软件开发中,大家都会遇到过这样的问题:客户的一个新想法,就推翻了之前与客户经过再三讨论而确认定下来的需求。如果是功能性需求变更还会让人容易接受一些,毕竟功能性需求不实现的话,是会大大影响到软件产品的质量。但是一些非功能性的变更会让人很头疼,许多是看起来无关痛痒的、鸡毛蒜皮的变更,却是极为令人无语和无奈,甚至是烦恼和厌恶的。
(1)什么是软件需求?
在IEEE中,软件需求的定义是:用户解决问题或达到目标所需的条件或功能。一般包含业务需求、用户需求、功能需求、行业隐含需求和一些非功能性需求。业务需求反映了客户对系统、产品高层次的目标要求;功能需求定义了开发人员必须实现的软件功能。所谓非功能性需求,是指为满足用户业务需求而必须具有除功能需求以外的特性。包括系统性能、可靠性、可维护性、易用性和对技术和对业务适应性等。其中最常见的是软件界面、操作方便等一系列要求。
(2)非功能性需求变更的特点
让我们从客户角度和开发人员角度去看看非功能性需求的特点。首先,有些非功能性小需求从客户角度看起来工作量不大,但是实际上开发人员要耗费比较长的时间去完成这些小功能。其次,许多非功能性需求,如界面美观、操作方便等都是客户头脑一热、或领导一拍脑袋就部署下去的需求,往往是原来在需求分析阶段所没有注意的内容。
其实,非功能性需求是常常被轻视,甚至被忽视的。原因是非功能性需求描述很困难,它很难像功能性需求那样,可以通过结构化和量化的词语来描述清楚。在描述这类需求时候,我们经常采用软件性能要好、操作要方便、软件界面要美观大方等较模糊的描述词语。例如,易用性就同时涉及到美工和UI界面、人机工程、交互式设计、心理学、用户行为模式等内容。这类描述词语都是脱离了软件的执行环境,是对人和相关的场景的描述,因此很难体现到软件架构设计和具体的实现中。
国内的很多软件公司,对于这种情况趋之若鹜,认为是负担,影响软件公司的工作安排,工作量以及工作进度,直接导致了软件公司的效益,几乎是很多软件公司的最大隐患,因此我们如何认识、对待这个普遍存在的问题就成了软件公司以及员工需要解决的问题;
1)首先,要从心理上彻底根除对需求变更的恐惧,从认识上明确需求变更是软件开发过程中不可缺少的部分,从方针上明确需求变更的存在性和必然性;
a)从软件公司角度,认清自身存在的不足, 客观面对需求的变更
b)从职员角度,提高本身的业务和技术能力
2)从技术角度上使需求变更的处理简单化,明确化,增加可维护性;
a)使用更好的技术手段,设计更灵活以用来适应更多变的需求;
b)使用更完善的软件工程的理念,让软件各个步骤细化,更易维护和修改;
c)使用完善的测试流程,最大的降低需求变更带来的软件风险;
3)对需求变更进行有效的管理,让需求变更可以规范化管理,做到有效的处理需求的变更,用有限的资源获得最大的效益;
a)软件的初期,就要考虑最大限度的减少将来可能存在的需求变更
b)需求的控制,减少需求的来源,过滤不合理的需求
c)文档化管理,有备可查,有据可依;
d)合适的公司体制和运作,找到一条适合自己公司发展的运作体制和管理模式;
可能大家觉得上面说的话有些空,那么我就从技术角度上再具体的谈谈。
就像刚才说过的,需求变更是必然存在的。从技术的角度来降低或避免需求变更给我们带来的影响就显得极为重要。
1、设计之初,充分理解需求,更好对需求进行整理和规划,预测可能变更的需求。
需求难做,业务难做,非功能性的需求变更更是难做。所以当我们在收集了用户需求后,不仅仅是简单的分类,然后按部就班的开发,而是要深入挖掘需求,一些看似固定业务的需求,可能由于业务的变更而使得你的系统不能使用。我们要做的就是拆分需求,把一些可能会发生变化的需求拆开,改成工作流程可配置的。就像面向过程转向面向对象的那样,面向过程是死的,而面向对象重新组合后,就特别简单。
就说说我们刚做的这个收银系统吧,用户要求结账时,要打印小票,并自动打开钱箱。这就是最最原始的需求。但是我们最终把它做成了这样:打印机是外部设备,可以增删和配置;打印次数可配置;打印样式可配置;打印时,要判断打印机状态,非正常状态要给出各种提示(不一一列举);钱箱可以自动打开,也可以手动打开。另外还设定了许多功能配置:如禁用/启用全部打印机,禁用/启用某个打印机,是否打印订单小票,是否自动打开钱箱,是否显示错误提示信息等等(如图)。
我们把这个固定的需求,拆分成可配置的,这样就把这个需求可能的变更已经分析的差不多了。不论它怎么变化,我们的应对都会变得从容。就在前2天部署的时候出现问题了,打印机是新买的,不只是什么原因,在打印多个换行之后,就会失败,不能继续打印。这个问题是我们所料不及的,因为我们测的我们这里的所有打印机,都完美打印,而新买的也是同品牌,同型号的打印机。最终分析出这个问题后,我们不用更改系统,只要修改一下小票样式配置,就可以完美打印了。
小票样式设定(图):
硬件设置(图):
单个打印机设置(图):
功能设置(图):
2、系统完成之后,客户再提新需求后,要分析这个需求的深层次含义,分析客户要的到底是什么。对于一些需求,如果适合于大部分客户,而且改动很少,就可以完成,那么可以在下个升级版本中集成。而对于某些非功能性的需求,改动太大,或者基本的核心功能都需要更改的话,那么就不要先去急着实现,而是放置起来,等待系统需要进行大的升级或者重构时,再考虑添加。而且要防止客户滥用提需求的权力,对于一些不合理的需求,还要去引导客户,让他们理解这个功能的不合理的地方,从而重新修改需求或者放弃。