软件开发与测试管理
摘要:测试组不是开发组的助手;软件测试的阶段性;bug的发现和管理;秘密武器:测试用例和测试计划。
要想真正保证软件项目如期完成,不仅取决于开发人员,更取决于测试人员。
项目经理经常犯的错误之一,是以为只要雇用软件工程师就行,其他的人都不必要,或是让软件工程师占整个团队很高的比例。他们也许认为开发人员越多,写出来的程序也越多,这是错误的概念。项目的目的是为了完成软件,而不是完成更多的程序代码。在开发团队中,实际有一些工作是不适宜交给软件工程师做的。
要想真正保证软件项目如期完成,不仅取决于开发人员,更取决于测试人员。软件开发好像是在赶进度,而不是在演奏交响乐:交响乐是和谐有序而优雅的,而软件开发却更像是一堆排山倒海、蜂拥而至的工作。交响乐任何两个音符都不能相互抵触,整体表现出来的才是一段优美的音乐。在一切都不确定的软件开发过程中,让测试人员的“Bug指挥棒”来使大家知道什么时候该表现,知道什么时候该退后一点,正是微软将软件开发过程带向高潮的不二法则!
测试组不是开发组的助手
似乎没有谁比微软更重视测试的力量。在微软的产品组中,测试组是与产品规划组、产品管理组、开发组和用户教育组等并列的队伍。测试与软件成本的关系是,发现产品中存在的问题越早,开发费用越低,产品质量越高,软件发布后维护费用越低。在微软开发周期的四个阶段中,测试的目的在于保证软件质量,满足设计的要求和客户的需求;系统地揭示出不同类型的错误,并耗费最少时间和最小工作量;降低软件的开发成本和维护成本。
软件开发过程中开发人员很可能因为一些偶发的小事,或某种无关的灵感而不知不觉中偏离了实际的需要,暂时忘记了什么才是产品最该有的功能,把他们拉回原定轨道中的正是测试工程师。测试人员的职责是配合整个项目组保证按照预定的时间表完成达到预定设计目标的产品。测试人员的工作是具有整体性、持续性的软件开发活动中的一环,而不是偶尔拿出来点缀一下。软件产品的质量是由用于测试的资源、产品的功能和项目的时间表来决定的,是三者的平衡。对任何的一个产品组来说,无论是主观,还是客观上,都要重视测试工程师的存在,这是产品质量的重要保证。
罗马不是一天建成的。早期的微软开发队伍中也没有设立单独的测试组。那个时候的微软几百个人做几个项目,通常是程序员写完程序了,自己测试一下就算完事。后来微软的项目越来越大,软件越来越复杂,写代码和测试的工作要平行进行,渐渐产生了独立的测试组。一个重要的数字是,微软产品组中测试人员和开发人员的比例大约是1∶1。其实,要想真正保证软件项目如期完成,不仅取决于开发人员,更取决于测试人员。
测试组独立于开发组之外的好处在于,程序员总是倾向于认为自己设计的代码足够好,独立的测试组可以使测试人员在不带任何假设的情况下从不同的角度来测试软件,有利于保证软件的质量始终得到控制,并使测试资源得到重用和不断改进。但是,测试组独立于开发组之外,并不意味着程序员写完代码就扔过“墙壁”,等待测试工程师找到所有的bug,当测试人员认为他的工作就是测试程序,而开发人员认为他的工作就是写程序给测试人员测试时,如果你是项目经理,要小心了!开发人员的优越感会使测试人员感觉自己是被歧视的少数民族,这势必会影响到软件的品质。程序人员在写完代码、改正问题后必须完成基本的测试,比如代码的路径测试、单元测试和问题验证等。产品质量控制,存在于开发过程的每一个环节中。
有一个笑话,微软的测试人员工作时间长了,都有挑刺儿的习惯,下了班见了太太做的饭都要评价一番。对微软来说,那些聪明、细致、认真,有耐心,追求完美的产品,对用户有负责任的态度,思维方式独立又开放,既有足够的技术背景,但又愿意学习新的技术的测试工程师更容易得到“老板”的青睐。
软件测试的阶段性
软件开发的过程就像是一支队伍正在急行军,但跑着跑着这支队伍就会“散了架”,设立里程碑的作用就仿佛是到了某一个“点”,大家必须要重新整理步伐,实现同步。就测试组的工作模式而言,测试的阶段划分是与项目的进度相对应的。也就是说,测试人员应当与项目组的其他人员始终保持以相同的步伐“跑步”的状态,与整个项目的每一个里程碑配合,完成相应的测试工作。
把大项目划分成若干子项目的里程碑式的开发模式是微软软件开发管理的精髓做法,如上一期《微软研发方法(上)》所述,在微软的每一个产品开发周期中都有以下几个重要的里程碑:CC(Code complete:代码完成);Beta测试;RC(Release Candidate:候选发布);RTM(Release To Manufacture:投入生产),测试人员和产品组的其他人员一起,共同达到每一个里程碑。一个完整的测试循环应当包括运行所有的测试用例、Beta标准测试、bug校验和解所有的bug、随机测试。好的测试循环能够保证对软件质量有一个全面完整的评价,每个里程碑之前至少要有一个完整的测试循环。
在微软的产品开发周期中,在规划阶段当开发人员在做计划、编进度,进行功能实现的可行性研究,对计划的功能进行反馈时,测试人员应当研究规格说明,编写测试计划;在第二个阶段即开发阶段,当开发人员在编写代码、测试和调试的同时,测试人员应当开始设计测试用例,开发自动测试工具和程序,熟悉必需的环境、工具、软件和硬件,不断地丰富测试用例,直到达到CC(代码完成)里程碑——这个时候的软件可以进行一次整体测试,用户界面可能不完美但能够工作,可能有很多明显的bug。
进入开发周期的第三阶段,测试人员大显身手,展开大规模的测试,比如系统级整体测试,交互性和深层测试。测试之后,测试人员应当对新增的功能说“不”,直至达到Bate测试里程碑。达到这个里程碑,意味着所有的Beta致命问题已经被修正和关闭,所有计划的功能都已经在软件中并能工作,产品稳定,大部分界面还可以,尽管可能只是一部分,但已经有了在线帮助和用户手册,即使是发布了也不会引起负面的影响。
Beta测试的目的是确定产品是否能在预计的各种硬件平台和操作系统中正常运行,虽然Beta测试的反馈意见很有参考价值,但除非存在重大问题,否则不应对功能集再做修改,所有建议和反馈都留在下一版中再考虑纳入。Beta测试之后就要向RC和RTM进军。测试人员要着重测试Beta后的变动。到达RC,意味着软件质量状态为没有活跃的bug(Active bug);没有悬而未决的事;已经稳定了一段时间,如一周内很少或没有变动,或变动很小。如果RC后的测试没有发现新的需要改的bug,可以达到RTM,随后查病毒,验证光盘,检查内容。
需要注意的是,在整个阶段性的软件测试过程中,质量不仅仅是测试组的责任。一定要防止完全依赖测试组来保证质量的做法,否则结果只能是质量差、进度延迟。采用Zero-Defect策略的好处在于,可以同时保证产品的质量、进度和功能集,尽早发现和修正产品中的bug,始终把产品的状态和bug数量控制在可以管理的范围之内,程序员应该修正所有的优先级为一级(P1)的bug才能写新的代码。
同时测试组应当开发一些好的测试管理工具,比如测试用例管理工具和bug的管理工具等等。测试工程师应当细化测试子区域,重视测试用例的数量和质量,对bug状态的变化要反应迅速。要防止仅以bug多少来评价工程师的工作。
bug的发现和管理
在微软的测试人员看来,那些功能没有实现或与规格说明不一致的问题是bug;不能工作(死机、没反应)的部分是bug;不兼容的部分是bug;边界条件未做处理是bug;界面、消息、提示不够准确是bug;有时把尚未完成的工作也作为一个bug。微软把软件中常见的bug类型归为以下几类:功能错误;用户界面错误;边界值相关错误;初始化错误;计算错误;内存相关错误;硬件相关错误和文档错误。
测试工程师发现bug之后所采取的措施,首先应当是去想法验证是不是自己的偶然失误造成bug出现,如不是则应立即建立每一个新的bug记录,包括具体的再现步骤、环境、屏幕等;尽可能地分析产生bug的原因;设计合适的优先级和严重级别,要记住,测试人员的目标不是找出更多的bug,而是改进产品的质量;依据bug的优先级和严重级别分派给某一个相应的人,如程序员、项目经理和测试组的负责人等。
一般来说,bug在数据库中有三种状态:活跃(Active)、被解(Resolved)、关闭(Closed)。这三个状态在微软通常用“红黄绿”三个颜色来代表。活跃状态指的是测试人员新建一个bug时的状态,必须分派给相应的设计人员、开发人员或者是用户教育人员,表明bug的状态是等待纠正的。被解状态指的是设计人员、开发人员或者用户教育人员修正bug后的状态,必须重新分派给报告bug的测试人员,表明bug已经得到修正,但等待校验。关闭状态指的是测试人员校验完成并关掉之后的状态,表明bug已经得到修正,并完成了校验,但如果同样的问题再次出现后,还可能重新激活成活跃状态,则又开始了另一轮的状态循环。活跃bug数量的变化趋势是,一般在代码完成前很少,代码完成后增长很快,接近Beta测试时会下降,接近RC时奔向零。因此依据每天新建的bug数量与修正的bug数量相比较和处于活跃状态的bug数量亦可判断产品质量和里程碑的信号。
永远有缺憾是所有智力活动的特征。软件一定有数不清的缺点,问题不是在于判断这个产品好与不好,而是决定修改哪一部分从而可以使产品比较能被用户接受或喜爱。微软把这个判断并修改的过程称为“急救术”。在急诊室中医生必须非常迅速地察看患者面临的所有问题,采取最急迫必要的急救医疗措施,然后再依优先级分别施救。微软产品组也一样,他们把bug的严重性分为四个级别:导致死机;主要问题,导致严重的问题,如某个小功能未实现;小问题,不太严重,如提示信息不太准确;微小的问题,如有个别错别字。把bug的优先级分为四个级别:尽快修正;每个里程碑结束前必须修正;如果时间允许就修正;低优先级。微软有“bug法庭”,通常由程序经理召集,由项目经理、开发负责人、测试负责人组成,可根据产品的功能区域分成具体的“bug急救小组(bug triage team)”,审查每一个bug,选择和修改产品中最重要的错误,决定相应解决方案,尽量使大部分的用户在大部分的时间内都能够使用愉快。当然,“bug法庭”开会的频度取决于处于哪一个阶段。
测试组应当有一个区域专门放置记录所有bug的数据库。这个数据库应当是整个产品组的中央记录和控制区,而且其中所有的记录都无法删除,对于每个记录只能一直添加内容。测试组应当有与项目组所有成员交流与沟通的公用工具;与bug mail配合,能根据bug的当前状态及时通知bug的当前责任人;有效地跟踪项目的进展,为产品发布提供判断标准;能积累测试人员成果。
秘密武器:测试用例和测试计划
概括来看,微软测试的精髓做法是:系统可重用的测试用例;以问题(bug)发现和跟踪为核心的测试活动;独立的测试人员;基于产品规划、产品设计规格的测试计划;与整个项目配合的基于里程碑的软件测试周期。而基于产品规划、产品设计规格的测试计划和系统可重用的测试用例则是微软的“秘密武器”。
在微软,测试计划是帮助测试人员管理测试项目和发现bug的重要工具,是纲领性文件。测试计划明确了项目的测试任务、测试内容清单,这些内容不能只存在于测试人员的脑海里,而必须被项目经理、开发经理所了解,测试计划必须增强测试任务和测试实施过程的沟通,具有指导性。测试计划还必须提供组织管理测试项目的框架结构,帮助控制进度。
测试计划涉及的范围应当有产品概述、测试策略、测试的方法学、测试区域、测试的配置(软件环境、硬件环境、网络环境)、测试周期(与项目的里程碑配合)、测试资源的规划、风险分析和案例等。测试计划不是一成不变的。虽然测试计划在产品设计阶段就开始被撰写,但在后来的开发过程中会随着项目进度表的改变而改变。
一个好的测试用例有以下几个特征:首先,是最有可能抓住错误的;其次,不是重复的、多余的;第三,一组相似测试用例中最有效的;最后,不要太简单,也不要太复杂。因此,在测试人员设计测试用例时应当遵循以下原则:在人员变化和新项目中能够重用;能够分类; 测试的内容不重复;保存在测试用例的数据库中;在项目进行过程中可不断增强。
设计测试用例时的一些通常考虑“点”是:根据产品规格测试基本功能;设计普通用户的使用方案;设计稀有或特殊的使用方案;与系统其他组成部分的配合(如FAX和上网可能都要用到调制解调器,测试中要考虑对设备的共享);考虑特殊情况(比如内存和硬件的冲突等);设计极端情况(比如内存泄漏、破坏性测试)等.