前段时间InfoQ发布了《QA部门将会消亡》一文。
本文是一位测试专家对该文做出的回应。
就如同已经灭亡的皇室(国王已经消逝了,但是皇后却将永存),我们的软件开发正传递着类似的呼声:“测试已死,我们再也不需要测试人员了!”但随之你会发现,哎呀,客户不满意,最后又回到“测试万岁”,但这次是更好,更完整,更有效的测试。就如同历史上众多的复辟王朝(我最喜欢皇后伊丽莎白1世)一样,测试将强有力地帮助重新定义事物完成的方式以及它们的工作原理。
我打赌你现在正在想这不过是自我吹嘘而已,但是,事情是这样发生的:
让我们讨论一下测试的概念:什么是测试?测试就是考虑什么是“对的”的一个流程,定义方法以判断所测试的事物是否是“对的”,确定度量以明确“对的”是什么样子,理解“对的”的等级对团队其他人的任务和活动意味着什么,还有协助团队根据有用的信息做出好决策从而满足“对的”所必须的等级。
测试远不止随机敲击键盘以期找出问题这么简单;测试需要真正地理解所要求的解决方案,参与交付产品所采用的方法计划,了解交付方法所含的风险,同时还要尽早发现这些风险以便采取合适的补救措施。测试还需要驱动项目往成功的方向发展,并且帮助每个人理解成功所要求的合适水平。
为什么我们还需要关注测试呢,敏捷团队中的每个人不都在做测试吗?事实上并非如此。
所有的争议都是从质量的概念开始的。可能你会对自己说:“这简单。”如果你确实是这么想的,那就把它推到下一步…定义它。让你的开发团队、客户、产品所有者、项目经理以及组织中的首席信息官和首席执行官定义质量,要好好地定义,定义到足够好的程度。他们会同意吗?如果不同意,那这就是你的第一个问题。测试的任务就是帮助团队定义和理解质量所带来的影响。
“质量的影响??这是什么?”这是你的下一个问题。事实上:质量是需要成本的!更糟糕的是:真正的高质量需要更高的成本!想真正建立质量,我们首先必须定义它,然后需要找到它。如果没有将质量建立到流程和技术中,没有将完整的各个级别的测试构建到我们的工作中,就不可能实现质量解决方案。
“啊,总算逮住你了”开发人员说道,“我们在敏捷中通过定义“完成”来明确质量”。“垃圾!”是我的答复。在我从事IT的所有时间里我听过最让人兴奋的概念就是定义“完成”—所有的组件,集中所有的知识,传递所有的信息……将解决方案的复杂性预先定义,所有的团队(开发和客户团队)都知晓所需要完成的任务以达到“完成”。定义“完成”让我想起了测试相关的一切。但是坏消息是我们并没有这么做!是的,我们没有这么做!就像我们不定义质量一样……我们只是假装我们定义了而已。哇~,
是否刺到你的痛处了?
为什么我这么说呢?首先,定义“完成”就如同定义质量一样,非常难。因为质量就像“美丽”一样,它是一个仁者见仁,智者见智的问题。测试的内容包括接受培训从而关注质量的定义,紧接着是对质量的探索(或者是质量缺陷),还有就是沟通在项目过程中依据进程、风险和剩余工作明确质量等级意味着什么。对于“完成”的定义也是如此,对于每个“执行者”(非旁观者)而言“完成”是不一样的,这允许我们理解“完成”的多个层次……我的完成,我们的完成,故事的完成,迭代的完成,特性的完成,发布的完成,产品的完成,项目的完成。
“这个没有关系,我们可以在其完成时再定义。”这是你对这个问题的机智回答。现在真正的挑战来了!定义“完成”与定义“很好地完成”是完全不一样的。“很好地完成”中的“很好”不仅仅是要完成目前产品中所要求的工作,还要明确我们如何知晓它达到了被要求的标准。每个层次的“完成”都有不同的完成标准,以及一个非常不同的“很好”的质量标准。团队中就有一群人不仅非常适合于协助定义“很好地完成”,同时还可以协助定义用于寻找“干得好”等级的流程和技术。
步骤一,定义“完成”…嗯,这看起来很简单嘛——保证执行者按照“完成”的等级完成所有需要交付的组件。好吧,目前为止听起来还不错。但是紧接着难点就来了…如果客户不满意,那么任何事情都不算“完成”。这就是敏捷宣言的基本属性之一。我引用了“可工作的软件胜过面面俱到的文档”这句话。因为一些不为人知的原因,人们往往会混淆“可工作”的定义与“完成”的定义,同时还会混淆“面面俱到的文档”这一概念与“良好测试”的定义。然后这就违背了原则“我们的最高目标是通过尽早持续地交付有价值的软件使客户满意”。那么是什么使软件具有价值呢?是不是交付产品?当然不是!而是该软件能很好地完成它所要完成的工作!!那么这算是我的“完成”,我们的“完成”,还是什么的“完成”呢……?
我们该如何去做呢?首先,我们需要认识到测试不仅仅是考虑开发和用户所关注的功能。功能要实现什么是非常简单的部分(简直就是轻而易举——我发誓)。功能很容易定义、构建和评估。功能倾向于二进制,类似“完成”与否的!“完成”有两个等级……“完成”和“未完成”……没有什么“几乎完成”这类说法。功能类似于煮食物……只有能与不能工作之说……二进制!但接着我们就进入了“完成”和随后的“很好地完成”领域,甚至更进一步的“为谁很好地完成?”。
测试关注于理解什么能使一个解决方案或方法对于使用它的人有价值。价值是上下文独立的,并且必须在项目和客户的上下文内定义。使用类似ISO9126之类的标准,根据它的6个质量特征(功能性,可靠性,实用性,有效性,可维护性和便携性)及其子特性,可以激发测试人员针对什么是好的、恰当的、有价值的这些问题进行讨论。但是更好的是我们需要真正的测试来找出这些价值。这类测试同样也需要时间和计划来很好地执行,如果想做得更好地的话,就需要更长的时间。
一个解决方案中的所有非功能特性都是设计层特性,并且通常不能在迭代中演变。需要预先对其进行讨论,而且需要在解决方案确定时尽快讨论,是的……在解决方案设计确定时尽快讨论。如果这些特性在最开始没有被正确嵌入的话,那么它们最终永远都不会在测试中被找到。单元测试能做这些吗?当然不能!
“噢~~~,这就是为什么我们做验收测试驱动开发啊!”你说。我同意,但是我们往往并没有将ATDD做好,我们只关注客户所知道和所问的内容,而没有关注前期需要考虑和捕获的内容。
“那我们就只关注功能吧。”这是我经常听到的一句话,往往让我感到厌烦……这意味着很难想到其他的事情,我们只好继续前行,并祈祷它是对的。你是否“曾经”听过“忽略”敏捷呢?敏捷就是要从一开始就把事情做对。
测试通过静态测试从一开始就协助建立正确的解决方案。静态测试是“不通过执行代码来测试解决方案”。静态测试之美在于它可以在任何时间和任何地点执行。静态测试应该在解决方案的第一个想法产生时执行。理想情况下,应该有个测试人员提出这样的问题:“这是功能不错……但你是如何确定它是有价值的呢?”通过问题,图表和该解决方案的计划来测试该概念以查看它是否真正交付了所需要的解决方案,这是产品生命中至关重要的一部分。
我们还可以测试交付计划,关注风险、时间以及各组件间的依赖,以及如何利用不同等级的“完成”来证明我们正在往正确的解决方案行进。往“很好地完成”的方向上定义“完成”需要正确的人在工作初期就参与进来,而不是在编码已经开始之后。测试计划是至关重要的——是否定义了正确的环境、团队、资源和方法来交付价值?这是一个问题,但往往并没有在编码前得到回答。这个奇妙的新测试制度的存在引发了这个问题,并且所有人都在前往下一步之前就把它回答了。
测试计划的完成可以通过使用测试设计技术预先定义接受标准。你可能会喊道:“什么???已经开始测试了???”是的,完全正确。如果不提前执行的话,那测试人员获取的那些培训和证书又有什么意义呢?你看到测试人员所做的大部分测试执行活动都是他们基于风险和测试设计技术规范而形成的测试设计活动的结果。概念、特性、长篇故事和用户实例其实都只是规范在不同名字下的转译。更好地,在理想的敏捷世界里,测试人员会参与到需求定义中,这样他们就能够静态测试它们,然后可以在任何人试图实现一行代码前对其应用动态技术。
接下来,我们开始真正的工作(轻笑……任何人如果觉得编码前的工作不是工作的话,那他并没有理解工作的概念),我们开始编码,做单元测试,改进代码,做集成测试,将代码发布到测试环境(咚,咚,咚……鼓声响起)……我们开始尽全力寻找紧急行为!
紧急行为——这是测试人员在敏捷队伍中的真正价值:关注模块、代码和用户故事如何结合在一起从而交付所需要的功能。但是我们都知道这些地方往往是那些重要bug的藏身之处。bug只有在我们开始多方位查看解决方案时才会露出端倪。测试人员的技能就是在系统中根据客户需求和路径风险设计这些路径,利用测试技术定位需要关注的重要区域。这里是决策表和有限状态模型(比如:N-1切换覆盖)真正发挥作用的地方。那些在单元测试或集成测试时没被发现的缺陷,会让验收测试立即崩溃。
在系统测试过程中,设计测试发掘具有风险的紧急行为,提供具有实践经验的证明来评估覆盖率、遗留风险、缺陷密度、开发进度等其它质量属性也是测试人员应该具有的技能。当然我并不是说开发人员或BA不能做这些,只是他们太过忙于自己的工作,往往没有时间或精力去想这些。同样我建议测试理念和技巧在计划、执行和报告这些问题上是最有效和高效的。
这把我们带到了确认和验证的讨论。它们的不同点到底在哪里?验证是确保所建立的东西是正确的——符合标准,遵循模式,在正确的时间做正确的事情。确认在另一方面是定义正确的事情是什么!确认和验证这两个部分都必须完成,测试给了我们完成这两部分的技术和技能,同时也允许我们将这两部分覆盖到系统需要的各种属性上(例如质量)。
下一个问题是“那我们还需要测试人员吗?”恕我直言,--需要!!!为什么?因为测试实践人员所想的与团队里的任何人都不一样。测试人员是“专业的悲观主义者”(ISTQB基础教学大纲)。好的测试人员会花费时间关注潜在的问题,而非潜在的解决方案。从一开始我们就考虑坏的消息——到底哪里会发生严重的问题,如何快速定位问题,甚至如何去阻止问题发生。这和敏捷概念中的“快速失败”和尽早理解风险这两点完美切合。我们需要这样的思想观念尽早地参与到项目和解决方案设计中,从而让我们能够尽快并尽可能多地发现潜在障碍。
真正拥有足够多的测试知识,能够准确计划测试工作的人并不多,而敏捷团队中需要关注的哪里和何时需要测试的东西又太多。在用户故事等级测试,迭代等级测试和特性等级测试之间应该有个明确的界限;还记得之前讨论过的“完成”的等级吗?由谁,在哪里,何时完成哪一部分测试都需要明确地确定出来,以保证所有的环境、工具、技术、数据和人员在执行时的有效性。测试(就像大部分事情一样)在好的团队中并不是偶然发生的……好的测试会做优秀的计划。优秀的测试需要杰出的计划。在该计划中,需要紧密地考虑测试人员和测试以保证所有相应的安排都建立到位。
你是否会问:“那测试人员如何做到这些呢?”大部分人认为测试只是测试执行,但是在现实世界中,你所看到的那小部分测试是测试中最简单的。执行测试用例花费了总体测试工作大约25%的时间。大部分测试是在思想和文档中完成的。“天哪!”……你被震惊了……敏捷不是说了吗:“可工作的软件胜过面面俱到的文档”!没错!但是测试可以在任何或全部文档中发生(故事实例、白板设计、验收标准等)。第一个也是最大的一个障碍是,人们或整个团队不愿意定义什么是“很好地、价值、完成”,或者由于太难而不愿将它们细化。
多样的团队允许我们掌握每个方面最好的那一部分。特意排除某组技能或某组知识是幼稚的,非常不成熟的行为,且不能提高解决方案或方法的长期性。一个完整的并且拥有能够在最好的可能时间以最优惠的可能价格交付最好的可能解决方案所需要的所有技能的团队,才是完全聪明的、优秀的业务团队。认识到团队中其他人的技能,并将它们最大化发挥出来也是聪明的举动。
那测试人员需要有自己特有的团队吗?不需要……敏捷项目中的任何人都可以成为测试人员,事实上,敏捷项目中的所有人都是测试执行者。主要问题是,团队中的所有人都需要遵守纪律,为了完成必须的所有测试活动(不单单是测试执行)他们需要在日常工作中时刻做到“测试先行”。如果团队没有在他们的工作产品、方法和解决方案中花费时间或精力计划、设计并应用测试,那团队将无法知晓他们的进程以及他们所面临的问题。
因此我能留下的建议是:
1、确保整个团队对每个层次“完成”的定义有个明确且一致的理解——自己的任务、用户故事、迭代、发布、项目和产品
2、确保整个团队对这个产品的“质量”概念有个明确且一致的理解——是什么构成了“可工作的软件”
3、测试并不只是敲击键盘以期找到缺陷,也不仅仅是执行单元测试
4、测试是整个团队的责任,应该从第一个概念的讨论开始,并涵盖敏捷项目中的所有方面
5、尽早测试,并且经常测试——等到所有工作完成之后才开始想到测试是错误的
6、静态测试(检查每一块工作以确保其达到质量要求)比执行测试用例更有价值
7、设计好的测试是个专业活动,敏捷团队中任何人都可以做到,但是需要一个正确的理念
测试在敏捷中是否灭绝了呢?是的,但那是传统的,过时的,生命周期测试末期的测试。新的,完整的,预先的,积极参与的,挑战思想模式的,挑战现状的,并允许团队交付…交付价值,交付
“可工作的软件”,交付客户真正想要的解决方案的测试将会永存。
|