软件开发项目管理的案例解说(四)
来源:广州软件开发 编辑:广州软件开发公司 日期:2017-03-20
软件开发项目的执行管理 — 系列 (四)
引言
在上一期(今年六月份)的《程序员》杂志里有关软件开发项目管理的系列文章中,我将软件开发项目中进行设计总结的设计规范书(简称Spec )的撰写纲要及管理过程做了解释,并介绍了微软在产品开发中的一些相关的企业文化和传统。
在这篇连续文章里,让我将讨论的话题从前面几篇文章所着重讲解的有关开发项目的计划工作,转到软件开发时项目管理的具体执行工作上来,并进一步介绍微软在产品开发上的许多独特的管理方法和企业文化。
使用统一的纠错和更改管理系统是开发运作管理的中心
当一个软件开发项目完成了计划、开始进行具体的开发工作之后,一个开发组织的各种工作结果反映在各个团队随着项目的进程所完成和呈交的各种提交物上,它们包括:开发团队呈交的软件功能组件的源代码、文档编辑团队呈交的各种文件、使用界面专家设计的各种使用界面的资源、可用性专家对用户进行的可用性的验证和调查结果的总结、测试团队对以上呈交的各个工作的成果进行测试的结果以及各种测试记录、等等。所以,任何一个大型和复杂的软件开发的过程是一个需要整个开发部门的各个专业团队进行良好配合和协作的过程。
要协调这么多人的工作、使大家能够进行良好的配合、将大家的工作结果都为达到项目的整体目标而出力,是一个不简单的管理任务。要做到能够有效地进行整个开发项目执行过程的管理,光靠简单化的记录工具和原始性的手动管理方法是远远不够的。开发组织需要遵循开发管理的执行规章和使用高效的管理工具。这也是区分一个开发组织或企业是具有成熟的管理能力还是仅仅具备小作坊式的原始管理能力的衡量之一。
在这样一个有多个团队进行同步工作的环境下,不同团队的工作结果和质量会影响到其它团队下一步的工作,比如程序开发的质量会影响到测试工作的范围和工作量。关系到软件开发的实际结果的,就是这些在一个环节出现的差错和问题对下一个环节所造成的影响。所以真正有效的管理,就是要在每个可能出错的环节,用必要的运作流程和规章制度的执行,来尽量保证各种差错或问题被及时抓住,保证每个环节的工作结果符合必需的质量标准。
那么,我们如何来保证每个环节的问题(即出现的差错和缺陷,我们通称Bug)都被及时抓住、被注意到,并有相对的措施来保证它们被及时解决呢?
答案是,在每个环节都进行质量的把关,将进行质量把关的检验及时地记录下来,并要求整个开发组织的各个团队都严格按照统一的方法进行检验和记录;对于发现的问题该作如何的对策,这个决定手段和过程,整个开发组织也必须按照统一的规则来进行。
微软在这方面经过自己三十多年产品开发的实践和经验教训,总结出了一套极为有效的开发管理的运作流程、和与其相配套的独特的开发管理工具。这一套极其特别的管理方法和使用工具,是一个建立在现代项目管理的理论基础之上的具体实践。它的关键理念就是:任何有效的项目管理都离不开扎实的更改控制管理(Change Control Management),通过共同使用统一的纠错和更改的追踪和管理系统(Bug Tracking and Change Control Tracking and Management System)的工具,建立与之相关的有关规章制度和企业的文化,来达到有效的开发运作管理。我在《软件开发项目管理》一书中对这个系统的使用作了详细的论述,这里我来对其基本概念作一个简单介绍,并谈谈微软在开发管理中与其相关的企业文化。
把更改请求记录的统一使用与代表团队意见的审核结合在一起
如前所述, 开发工作一旦开始,每个不同的环节(即每个不同部门的工作结果)都有可能出现差错和缺陷。我们管理的关键方法就是要使所有这些部门使用统一的差错追踪和记录工具,用它来帮助我们将每个团队的工作给连接起来。当任何问题被发现后,发现问题的人将差错和缺陷(即Bug、或称“害虫”)记录到对差错进行追踪的工具里去。这样的工具带有自己的数据库,所以可以很容易地对缺陷记录档案进行搜索。任何Bug一旦被记录下来,它就“逃不掉”了:再也不会被忽略或遗忘,因为负责项目管理的项目经理,会定期的(比如每天一次)对所有的缺陷记录审核一遍,并与其他团队的领队或成员对每个Bug做出如何处理的决定。所以采用统一的记录和定期的审核,首先保证了任何作了记录的问题都得到开发组织的审查。我们在微软的传统是,没有经过Bug Tracking工具记录和决定的任何要求,开发团队可以采取不理睬的态度。我们的口头禅是:“If you want that issue to be fixed, file a bug!”。微软为这样管理流程开发了专门的供内部使用的纠错记录工具,叫Raid,这几年又升级换代为Product Studio。现在,这些工具的功能已经被整合到最新版本的Visual Studio Team System(VSTS)中了,所以任何软件开发公司或进行任何信息系统开发项目的企业,现在都能够借鉴和使用微软的优秀开发管理传统,使用VSTS对自己的开发项目进行同样的高效开发管理。
在微软,我们把每天对纠错记录进行审核的会议昵称为“急诊室的会诊”(Triage,意思是像对急诊台上的病人进行手术前的会诊一样),或也叫它为“三国会议”,因为这样的会议必须要有项目管理、开发、测试三方都有代表参加才能召开。如果项目经理要召开Triage Meeting了,可是会议室还缺少三方中的一个代表,比如测试团队的领队缺席,我们要么马上打电话去找能代表测试团队意见的测试工程师来代替、要么将会议推迟。这样的良好风气和传统保证了代表软件开发的关键三个方面的意见在审核每个Bug时都能被听到和得到尊重。如果某个Bug是与文档编辑或使用界面有关,则在做审核的决定时,三国会议会再邀请文档编辑团队或使用界面设计团队的人来参加。这样的规则保证了任何决定都是有熟悉情况的做具体工作的人的参与,避免做出不符合实际的荒唐决定。
这样的记录追踪和管理的方法,不仅对软件的缺陷进行纠错和修订采用、更是对其它任何改动要求也使用。比如说,要是在软件开发过程中发现原来的设计有问题、需要加入新的功能,找到问题的人也是通过记录一个要求对设计进行改动的Bug(我们把它称为DCR,即Design Change Request)去要求三国会议对它进行考虑,而不是径自或随意去要求项目经理做设计上的改动。所以严格说来,这样的管理不仅是对纠错要求做管理、而是一个对任何更改要求做管理的方法和系统,所以它是一个全面的更改控制管理系统。
使用这个更改控制管理的最根本的精髓在于,任何缺陷的修改、或对功能需求改动的请求,不是随便可以接受的,已经开发的程序也不是可以任意由开发者随便加入新的功能做改动的。修改缺陷或加入新功能等所有改动要求都必须经过“提交请求→分析批准→改动程序→验证改动→改动完成”这么一个运作流程,来保证改动的要求是合理的、是与项目的目标一致的,同时也保证任何改动符合必要的质量管理要求。下面图1是一个完整的执行纠错和更改请求管理的运作流程总结(详细解释请见我书里的叙述)。
既然这样的管理工具和规则要考虑到对任何可能出现的改动要求进行审核批准,在使用时就必须要有一套可以顾全到各种情况的、可以帮助进行衡量和审核的标记。在纠错中最常用的方法是对任何问题进行不同级别的重要性(Priority)和严重性(Severity)的划分,比如P1到P3、S1到S3这样的级别划分。这个设定级别的方法也可以用到对任何改动请求进行管理的更改控制管理中来。图2是用来帮助进行更改管理的各种划分标记和使用的范围。
你将图1的操作流程和图2的衡量标准结合起来,就可以建立起一个完整的开发过程中进行纠错和更改控制管理的制度和规章。我们在微软所进行的产品开发就是按照这样的方法来进行项目的执行管理的。它充分尊重软件开发的三个中心团队的意见对开发的成功所具有的同等重要的影响,用一个组织手段来保证软件的设计、开发、测试三个方面的考虑都受到重视,同时还照顾到其他各个辅助性团队的意见不被忽视。微软30多年的历史证明,这种管理流程和方法的灵活性,具有巨大的好处,它使开发团队能保持做决定的灵活性、快速性;帮助公司保持产品开发的效率和速度、保持对市场的高度灵敏的调节能力,所以它对微软的整个企业的成功有不可估量的重大贡献。
进行更改控制管理的具体操作方法
下面,我仍将自己在微软进行过的嵌入式操作系统工具的开发项目管理作为案例,来举例说明如何使用这样的工具和规章来帮助进行项目的执行管理:
首先,当开发项目开始进行以后,我们整个开发部门各团队就开始统一使用我们专门的纠错和更改管理系统Raid(后来升级到Product Studio),用它作碰到的任何问题的记录。比如测试团队在产品中找到的缺陷、任何人发现的产品设计的问题、以及任何一个团队所呈交的工作结果中的被发现的缺陷和问题、包括产品文件、使用界面设计、本地化翻译等等。如果市场营销部门有客户回馈或增加新的功能的要求,也用同样的方法提出要求。
我作为产品的项目经理,每天定时召开我的“三国会议”,和开发、测试、和其它团队的领队或代表,对所有的请求进行逐个审核,讨论对策、做出应付的决定。在会议上,打开Raid工具,并将计算机显示的数据通过投影仪投射到会议室里的一个大屏幕的荧光屏上,使得参加会议的人都能看到同样的内容。每天的会议我首先搜索所有的Consider Bug(Raid/VSTS这样的工具可以根据图2中不同的标准进行搜索),Raid就会用列表的方式将所有的Consider Bug给列出来。然后我就可以根据某个衡量标记来进行排序(Sort),比如,根据问题的优先级(P1-P3)、严重性(S1-S3)等等来排序,Raid/VSTS这样的工具就会将列表重新排列,比如将最优先的排在前面、同样优先级别的则将最严重的排在前面,等等。
先搜索和处理Consider Bug,也就是先考虑自从前一天的会议以来新发现的“加以考虑”的Bug。就像图1所示,所有新发现的问题都先用“加以考虑”提交“三国会议”作处理,所以这个做法就是保证新找到的问题马上得到团队的审核和做出相应的决定。对所有的问题和更改请求我们做如下的处理:
• 对设计的问题进行改动:如果改动请求是要求增加功能、或发现原来的设计有问题、或是Spec里面有错误、需要做改动,这类的更改要求就是DCR。如果是小问题、很容易改动,我们就将这个Bug的属性从Consider换成Must Fix(必需修正),同时将更改的类别划分为Spec Issue(设计规范书问题),把它分配给相关的项目经理去对设计规范书进行修订。如果设计改动是复杂的大问题,那么我们就将这个Bug的属性从Consider换成Investigate(进一步调查),分配给相关的项目经理先去调查新设计的方案,然后将调查结果再次通过Consider 来呈交。
• 对软件的缺陷进行改动:如果改动请求是因为在软件中找到了一个Bug、要求批准将其纠正,那么我们对它采取如下处理:根据具体的情况来决定是接受改动请求或拒绝请求。如果“三国会议”在做了分析和评估后认为这个改动的请求合理或足够重要,我就将这个Bug的属性从Consider换成以下某个种类:Must Fix (必须修改)、Investigate (做进一步的调查)、等等。如果是需要作修改,则进一步将更改的类别划分,根据具体实际情况按照图2中右边的某一个种类来设定。这样的纠错修改不仅是对软件源代码纠错可用,对整个产品开发中碰到的其它问题和缺陷的纠错也同样可用、例如文档错误、使用界面设计缺陷等等。
• 拒绝改动:不管是设计改动请求还是对软件源代码纠错的请求,在很多情况下我们的决定是拒绝进行改动。造成这样的决定的原因很多,就如图2中左边所列出的。碰到这一类情况,则进一步将拒绝更改的理由的类别划分,根据具体实际情况按照图2中左边的某一个种类来设定。
处理完所有未加处理的Consider Bug之后,接下来我再搜索所有的Active Bug,列出来让会议参加者一起讨论。这些Bug是在以前的会议上已经作了某个决定,但是仍旧还未解决的问题。通常我先查看所有的以前会议上设定的Investigate Bug,看看这些应该做进一步调查的工作还有多少没有完成。接下来,查看有多少P1或S1的纠错还仍旧处于没有完成的状态。因为从图1中你可以看到,任何缺陷被纠错之后,进行纠错的人应该将缺陷的状态从Active转换成Resolved,所以任何仍旧处在Active状态的Bug就说明开发团队还没有对它们进行纠错的工作。通常,我们还将各种Bug按照重要性和严重性进行排列和比较,以及挑选某一个缺陷的属性、种类等进行各种搜索和排列,比如查看某一个软件组件的Bug数量、某一个开发工程师的Bug数量、等等。
有的时候,我们会把Bug数量最高的工程师的名字公布出来,开一些善意玩笑,以此来激励每个人都必须及早完成他们的纠错任务,比如谁的P1 Bug数量最多,就在他办公室门上挂一把大扫把。那些得到大扫把的人会自觉尽快完成纠错任务,可以将这个象征羞愧的扫把挂到别人门上去。
进行这样的纠错记录和历史的查看,能够帮助我们洞察到很多项目进行状态的情况,让我们了解到整个软件的总体质量、每个团队的工作质量等等。比如说,你可以搜索和查看在过去的一周或一个月里有多少新发现的Bug、有多少得到Fix的Bug,这两个数字的比值就是发现率和纠错率(Find / Fix Ratio)的比较。这个度量值告诉了我们目前按整个软件的总体质量状况:如果新的缺陷的发现率高于每天被完成修改的数量(发现率 > 纠错率),那么软件源代码的质量还远远不过关。
与此类似的对各种缺陷的统计是极为重要的衡量软件开发质量的度量。我在书中一共列出二十种这样的衡量度量。进行这样的衡量,能帮助你对整个开发项目的进度、是否能够按时完成、是否能够达到预期的质量要求等等,提供一个极为难得的指南。正因为如此,在微软的众多开发团队中,我们常常将这样的各种项目执行状态数据和质量度量的衡量值绘制成大张图表,张贴在开发团队工作的办公桌走廊里,让大家一目了然地随时了解项目的质量和进度。在一个办公楼里我们常常会看到众多这样的张贴。
这样的度量值我们也拿它们来开玩笑或给团队提出挑战。有一次在纠错上已经落后的开发团队做出保证:一定在一周内将纠错率赶上测试团队的发现率,不然他们的领队愿意被测试团队剃光头。测试团队当然不甘心、就与他们展开比赛。最后结果是不仅开发团队的领队被剃了光头,测试团队还叫公司的记者来采访,将剃光头的照片登在全公司的新闻公报上。到下一个版本的开发时,开发团队就主动努力保持纠错率在一定的数量上。
建立自动接受代表组织决定的良好习惯
一旦对更改请求做出了决定后,像Raid/VSTS这样的工具可以立即将三国会议的决定通过Email将各种纠错修改的任务通知开发团队的开发工程师们。这也是使用统一的工具的好处,大大加强了管理的自动化程度。开发团队的任何人也可以在任何时候使用同样的工具对分配给自己的任务进行搜索和查看。
最后我需要提到的是,光有工具的使用是不够的,还必须要有与之相配的规章制度。除了大家都应该遵守任何更改请求通过统一的工具来呈交之外,采用这样的更改控制有助于建立一个自动接受代表组织决定的良好习惯。
这个用类似Triage的形式作为决定的权力象征有它的一个独特的奥妙,即任何决定可能有争议性的时候,将决定与任何个人分离开来,而用一个团体来代表决定的过程,这样可以避免人与人之间为不同意见而带来的摩擦、争吵和不愉快。往往某个差错该不该纠正,开发团队的人会有不同意见。如果一个改动的决定是由某个项目经理或某个测试工程师强加到某个开发工程师的头上,一定会造成两个人之间的争论或不愉快。三国会议的形式将任何个人的喜好、取舍和决定,经过会议内部的争论、通过少数服从多数这样一个民主决策的过程之后,变成一个组织机构的决定。开发团队的任何人都愿意接受由三国会议传下来的决定,因为大家知道,每个决定在做出之前,已经经过三国会议内部的争论,各方面的因素都已经都被审视过了,决定来自于一个群体而不是一个人。所以这种方法可以很容易使所有决定得到贯彻执行、同时又避免不必要的人为摩擦和不愉快。在微软产品开发过程中,任何人可以将不同意见拿到三国会议去讨论和争论,可是经过讨论和争论后,结论一旦做出,所有人都被期望去不折不扣地执行。事实上,凡是Triage所做出的一切决定,从来没有被拒绝不执行的。这也是微软的这一管理实践和文化的巧妙和利害之处。
微软的这套深具灵活性的运作方法和它独特的优越性,是它的产品开发管理中真正的精华所在。它是一个看似简单、容易理解,却又是一个真正考虑到软件开发项目特性的、融合进传统管理理论中最优良因素的管理方法。现在,VSTS这样的工具已经公开发行,你也应该去推动你的开发团队建立和执行类似这样的开发执行的运作管理,来大大提高你们开发组织的效率。
在下一期的文章里,我们再来讨论如何运用这些质量度量来帮助进行软件开发的质量管理、和进行测试实践的一些指南。
软件开发过程中的测试管理-系列(五)
从上一期中的连载文章开始我将系列文章的重点转到了项目管理的具体执行的内容上。这篇文章中我继续来讨论与项目管理执行有关的具体工作和方法,着重讲解软件开发的测试工作。
测试是开发中必不可少的工作
首先,一个软件产品或系统的开发成功,不仅仅是编写完为使用者提供服务功能的程序而已。软件程序编写的完成,其实只是完成了开发任务中的一半。与程序的开发相配合的、具有同样重要性的另一半工作,是对开发完毕的软件所进行必要的测试。对测试的管理和执行,其重要性不亚于对程序本身的开发。你可以花费巨大的资源和努力进行程序的开发,可是你要是没有与此配套的完善的测试,所开发出来的软件往往会因为质量问题无法满足客户的要求和帮助你赢得市场的竞争。
近几年来国内信息业界的软件开发的成熟程度大大提高,很多公司都开始重视软件测试的重要性、并建立了与此相关的组织结构来保证测试工作得以执行。但是忽视或轻视测试工作的不良习惯和企业文化仍旧普遍存在。在中国项目管理俱乐部的网站上有业界的同仁们反映了这样的情况:他的公司居然还采用所有的软件开发人员都只做程序编写、只有一个人担任软件测试工作这样一种组织结构,而且这个公司的领导认为只有程序的编写才属于实际的开发工作,因此只知道夸奖程序编写人员的工作成果、完全忽视测试人员的贡献。虽然这样的近于荒唐的例子可能是极少数的极端现象,但在相当大比例的软件企业中测试人员往往仍旧是被当作“二等公民”看待,好像他们只是开发人员的配角而已,对软件最终是否合格和能否发行的判决,并没有实际的影响力。
一个成熟和高效的开发组织应该、也必须采取与此完全相反的做法:将软件的测试和开发放到同等重要的位置上,对软件的测试和开发给予同样程度的重视。这种项目管理的理念就要求对软件测试给予与软件开发相同的资源和支持,用同等的组织结构和人才来保证软件测试得到严格的执行。
微软公司就是用组织结构来保证产品开发的运作流程充分体现对软件测试的尊重、承认测试的重要性。微软总部各个产品部门的所有开发组织都有与程序开发团队并列的测试团队 – 任何开发组织都是由项目管理、软件程序开发、和软件测试三个并列的团队组成。这样的“三驾马车”的组织结构,保证了测试团队是一个独立于程序开发团队之外的机构,软件测试的结果和测试人员的观点在这样的组织结构中不会被程序开发人员随意推翻或践踏,测试人员能够大胆申诉测试结果、坚持测试的判决、包括阻止不合格的软件发行。我在Windows操作系统部门进行视窗嵌入式操作系统的开发工作时,就碰到过好几起因为测试团队坚持测试结果的审判,从而阻止了开发团队能够按时发行开发完毕的软件的情况。
敏捷模式中的测试驱动开发
事实上,现在最新的软件开发项目管理的模式之一甚至将软件测试的优先权提高到高于软件功能本身的开发之上。在敏捷模式(Agile Model)实践范围中的测试驱动开发模式(Test Driven Development,简称TDD)要求将软件的测试机制和可测性首先开发到软件中去,把对软件进行测试的功能作为软件功能开发的不可缺少的一部分来对待。它要求所有软件功能组件都必须有自己的进行自我的单元测试的机能、并且要求程序编写人员在开发软件的功能程序编码之前,先开发进行这些功能自我测试的程序。测试的程序编写完成之后,就开始进行单元测试的运行。这时候,由于提供功能的程序源代码都还没有编写,所以刚开始的时候这样的自我单元测试当然都是通不过的。当这些单元测试都能运行之后,开发团队然后才开始编写每个单元里面的具体功能的程序。
由于进行自我测试的程序已经完成了,每个功能开发完了之后,开发人员就马上可以启动单元的自我测试程序。要是单元的功能程序开发得完善,这时单元的自我测试就能通过,单元的开发就算完成了,测试人员再进一步进入到下一步的其它测试,比如使用案例的测试和系统整合的测试,等等;要是单元的功能程序在开发中有问题或缺陷,这时单元测试就还是无法通过,那么开发人员和测试人员就先集中精力来分析到底是什么缺陷和错误造成单元组件的功能程序无法通过那些自我测试,然后可以根据测试失败的症状进行单元功能程序的纠错工作。
举例来说,如果我们需要开发一个进行文档选择的功能组件。采用传统的开发方法的话,就是开发人员先将文档选择的功能程序开发出来,然后进行黑箱效应测试,证实文档能被选择之后就完了 。采用TDD的开发方法,我们就不是先开发如何选择文档的功能程序,而是先考虑这个组件该如何进行单元测试。所以开发人员先编写在文档选择的使用过程中进行检测可能出现差错的测试程序。这些测试检验代码的白箱效应的测试,比如进行文档选择后的数据检查、以及程序的逻辑检查等等。等到这些单元测试程序完成并能够运行之后,再开始编写实际的文档选择的功能程序。每个局部功能程序编写完毕就立即运行单元测试,直到单元测试全部通过为止。这时开发人员也可以根据软件构架设计的有求,对功能代码中的一些运算方程函数进行模块优化性的分解(也叫Refactor),除去任何重复的代码等等。任何源代码改动和分解之后,必须再次运行所有的单元测试,直到全部通过后才进行证实使用方案的黑箱效应测试,比如检测文档选择正确的结果、选择错误的结果、文档打不开的结果、文档找不到的结果等等。
这样的开发运作流程和管理的理念是,所有的程序都应该有它的可随时启动和利用的测试机制(Test Harness),而且这种测试机制应该是每个软件功能组件单元的不可分割的一个组成部分。我们首先开发这些提供测试机制的程序,建立一个可供测试的框架。然后通过先测试失败、加上功能后然后造成测试成功这样一种反面性的验证,来证实开发出来的软件是符合所设计的测试要求的。所以你可以看得出来,测试驱动开发的模式的主导思想是为满足测试而开发。
比喻来说,这就好像是修建一条铁道线,得先把铁路轨道的标准定了、轨道先铺上,然后再在铁路上运行与轨道宽度标准相符合、专门为它而造的火车。铁路轨道的宽度标准决定了所用的火车必须遵循的宽度。所以可以说,轨道宽度标准是一个制约了火车合格标准的框架。先有了这个框架可以很容易地证实造出来的火车是否符合要求。当然,你也许可以不顾宽度标准先造个火车再说,但这样造出来的火车不见得能在轨道上跑:要是轮距宽度不符合轨道标准,你就得返工重做。TDD的管理模式就是这个先造检测标准的理念在软件开发上的运用,就好像是你先定好轨道的宽度,然后说:按照这个标准造火车,不能在这个轨道上跑的火车就自动不合格;TDD的管理模式使开发人员建立同样的思路:按照这个测试标准去开发程序,通不过这些测试的软件就自动不合格。
这样的开发方法有很多好处,最明显的好处是“强迫”开发人员在设计程序的同时,并列进行必须进行的单元测试设计,催促你去思考如何验证你的程序单元的逻辑正确性和单元的完整性。更重要的是,这样的开发模式有助于推动进行自动化测试的工具程序的开发、提高测试的效率,因为那些事先设计好的的单元测试程序,在单元的功能程序编写过程中,可以被随时使用,来验证所开发的功能程序部分是否符合要求。
这样的开发项目管理模式和理念,很明显地是将软件测试的作用和重要性提高到一个开发战略的层面。 测试不再是简单的开发完毕后再考虑使用的质量管理的辅助手段而已,而是衡量软件在开发过程中每个单元组件是否能够通过,可以说是掌握了项目进度的“生杀大权”。
这个开发管理模式相对来说是一个比较新颖的方法,它对传统的开发流程的项目管理造成了不可避免的冲击,因此并不是很容易被开发团队接受,特别在绝大多数的在开发人员说了算的企业文化里,这样的开发方法的使用和推广很容易受到开发团队的阻力,因为它不仅用开发流程的改革来承认测试的重要性,并且由于开发人员被要求进行单元测试的开发和执行的额外工作 ,开发人员的工作量和习惯也都需要作一定的改变。
但是毫无疑问,这个项目管理模式所能够带来的巨大好处是有目共睹的。这也是为什么这几年来在业界中像敏捷模式、TDD模式等新型管理方法在软件开发的项目管理上被越来越广泛地利用。就拿微软本身来说,我们目前也正在进行一场内部的改革项目管理的“革命”:两年前,总部产品开发部门有少数一些项目经理们自愿组成一个推广敏捷模式的兴趣社团,在少数几个开发团队开始推动敏捷模式和TDD等。他们有点像个“地下组织”,因为绝大多数的产品开发团队还是在使用传统的方法,公司也没有人正式倡导敏捷模式等。但是近两年来,采用TDD等模式来充分发挥测试对质量管理起到的好处,很快就得到很多团队的共识,因为那些采用了这些模式的团队在软件质量的增进上有明确的数据可以证实,这种尊重测试的方法为提高软件质量、降低Bug Count(缺陷数)、最终帮助开发项目的成功所能带来的巨大好处。在好几次公司的经验交流会上,一些采用了敏捷模式和TDD等方法的团队公布详细的质量管理的数据比较,来证明这些新方法的优越性。微软快速适应变化的特性使得公司很快地也学会支持对新型模式的采用,现在全公司对技术员工进行开发工程教育的部门也开辟相关的课程,帮助一起来推广对敏捷模式和TDD等管理改革的采用,颇有“星星之火快要燎原”的气势。有的团队甚至采用配对的两人坐在一起开发的工作模式:一个人开发进行单元测试的程序,另一个人接着开发功能程序、并马上进行测试。两个人来回使用同一台计算机来完成对某个组件的开发。
完善的测试依赖全面的测试计划
前面讲述了测试对软件开发的重要性。那么在开发项目管理的运作中,究竟如何执行具体的测试呢?答案是:每个软件都有它的功能设计,通过它们为用户解决某些问题或提供某些服务。测试的目的有两个:第一是要确证这些为用户解决某些问题的功能设计被正确无误地开发出来了,也就是说,如果用户按照所设计的使用方法和过程(我们称为User Scenario,即使用方案),的确能够利用这些功能所提供的服务和解决问题;第二是保证软件在被使用的情况下,如果使用者并不按照所设计的使用方案在使用软件,它不应该由于任意的使用、或其它外部影响造成任何问题,包括出现差错,比如数据遗失、数据错误、 甚至造成系统崩溃等等。
为了达到这两个不同的测试目的,在执行具体的测试时就要采用不同的测试方法。为达到第一个目的、也是最主要的目的,最佳的方法是根据所设计的每个功能和使用方案,设计一个相对应的测试执行过程,去验证这个功能或使用方案是能够从头到尾完成的。这个测试执行过程的定义和描述我们称它为测试方案或测试案例(Test Case)。要能够确证所有功能的确是准确地被开发出来了,唯一的办法就是为每一个使用方案都设计出大量的、一套完整的测试案例(在微软的产品开发中往往都是几百甚至上千的测试案例在测试中被使用),然后通过对这些测试案例的按部就班的执行来证明软件的确可以完成所设计的功能。测试案例的全面性和完整性最终决定了为达到第一个目的测试的质量。
要能够做到制定完整的测试案例,就需要有一个可以作为依据的纲领性指南,帮助测试人员设计这些案例。这样的纲领性指南是由一份叫做测试计划的文件来总结的。测试计划在软件的设计规范书的基础上进行总结和撰写,根据具体的软件和使用要求,制定出整个软件产品的总体测试构思和设想、测试总体范围、对测试方法和测试自动化工具的要求和定义等等。在测试计划的基础之上,测试工程师们根据它再进一步制定详细的具体测试方案。至于测试计划该怎样写,该包括什么内容,我在《软件开发项目管理》一书的第十一章里有详细的测试计划文件的模版你可以参照使用,这里我就不再重复了。
应该同时满足测试的两个不同目的
但是光进行测试案例的执行、按照事先设计好的使用步骤来测试软件的使用状况,只能达到上面所讲的第一个目的,却无法满足第二个目的。原因是,当你的软件在众多的使用者手中被使用时,用户们不见得一定会按照你所设计好的、或所期望的步骤来使用软件,而是任意地使用的。这个时候软件就有可能由于设计得不当或内部的缺陷而发生各种不同严重程度的问题。这一类的问题光用测试案例的执行不见得可以找得出来、而且通常往往是找不出来的。所以与执行测试案例的执行相并列的,还需要进行一系列的与正常的使用方案并不一样、甚至毫无关系的测试。这一类的测试是尽量找出在非正常或随意任意使用的情况下可能出现的Bug。
对这样的测试目的,我们采用两种手段来达到:第一种手段是由测试团队设计并执行各种非正常性的测试,包括边界测试、压力测试、安全测试、以及进行一定数量的随机任意性测试(这些测试种类的详细定义见书中的解释)。这样的一些测试可以找出很多在正常使用情况下无法发现的缺陷。但是光靠测试团队的有限人力和资源,还是无法照顾到大量的随机任意性状态下可能发生的出错情况。所以你还得想办法“动员群众”来达到最好效果。微软的企业文化在这方面有两个很有意思的传统,值得国内业界的借鉴:
第一个叫“抓虫大扫除”(Bug Bash):在某一个版本的发行里程碑到达之后,在发行之前项目经理向全体开发组织发出通知,告诉大家哪一天的某个时间是Bug Bash的时间,到时候全体成员,包括开发、测试、文档等团队、甚至市场部门的员工,全都放下手中的工作,在规定的那一个或几个小时的时间里,每个人把自己当作是用户一样来使用这个未成品的软件,并且进行竞赛,看谁能找到最多的Bug。这样做的目的是,不是按照测试方案的顺序来检查软件,而是通过像真正的用户那样来使用软件,即完全是任意性的、无规则的顺序,看看在这样的使用条件下,还有没有仍旧没有被发现的严重的Bug。 我们往往采用谁找到最严重的Bug 就得奖的方法来鼓励大家尽力找出Bug。抓虫大扫除一结束,项目经理马上进行新呈交的Bug数量的统计,然后向开发组织中的全体员工公布。得奖的小有免费的咖啡、午餐、电影票等,大有各种礼物。所以每次Bug Bash 大家都踊跃参加,找到很多测试案例执行时没找到的问题。
抓虫大扫除对任意性的手动式的测试很有效,但对任意性的自动测试则效率有限。所以我们又采用第二个手段:“分享大家的计算机”(Machine Share):当我们在测试服务器产品时,需要模拟成千上万的使用者同时使用服务器的情况、或是需要模拟大量的黑客攻击的情况。这时候测试团队的机器往往不够用,还需要大量额外的机器加入到这样模拟中来。这时测试团队就会去逐个请求其他员工、 请他们在下班后不使用计算机的时候,在他们的机器上运行模拟大量使用或攻击的程序。谁的机器上的程序造成了服务器的崩溃或造成攻击成功,这个机器的主人就会得到一个免费的冰淇淋。有个人的机器连续三次攻击成功,测试团队还制作了一个巨大的冰淇淋画像挂在他办公室门前的走廊上,第二天上班大家都看到、并昵称他为黑客大王。
总结以上综述,完善的测试是保证软件质量的关键手段,而要做到测试的完善,需要制定完善的测试计划,同时还需要开发团队为达到两种测试的目的进行带创意的各种执行手段来找出各种缺陷和差错 。
这里对测试计划的管理理念以及TDD等概念作了一个简单的介绍。有关测试计划的细节、测试方法的种类等,你可以进一步参阅《软件开发项目管理》一书。在后面的连载文章里,我会再来阐述和讨论采用敏捷模式进行开发的一些实践指南。你要是对如何进一步提高你的软件质量有兴趣或有责任负责推动项目管理的改革,可以通过网络进一步了解业界在这方面的发展以及最新的动态。
相关阅读