如何保证质量?

现在,我依然能碰到一些敏捷开发者和团队,他们在项目中还未采用自动化实践,比如微测试,自动化集成测试和集成测试。这种现象存在主要是因为三种原因:

1.开发者没有看到它的价值

一些开发者技术好经验足,他们很少出错,自动化测试对他们来说是个额外的负担。当一些初级开发者在忙着改bug时,他们往往在做更重要的事,比如把他们的技术应用到系统架构上。如果团队中有这样一批开发者的话是很难实施自动化测试的。

2.PM没有看到它的价值

一些PM认为自动化测试是额外的工作。因为他们要忙着交付产品,没有闲工夫去做这些。然而,他们忽视了一个事实–在项目可以部署之前,项目的大部分风险和不确定性就是bug修复这一块儿。如果团队有比较强势的开发者和SM,我希望他们能说服PM认识到测试的价值,如果没有的话,也尽量能想其他办法去实施自动化测试。

3.存在一些老代码

有时,一些基础代码在自动化测试实施之前已经存在了,而且它们和很多代码紧耦合强依赖。很难给这些代码进行微测试。就算mock都不管用,因为要给一个测试创建很多mock对象,开发者就几乎不可能开始微测试了。

 scrumcn1387173713

通常,原因1和原因2会最终导致原因3. 在开始的时候,基础代码在没有自动测试的情况下还是可控的,因为代码量和特性的数量不多,要运行的回归测试也很少。所以,团队看不到他们后来将会面临的问题。随后,有更多的代码要进行回归测试,而且基础代码变得更庞大更难于理解,人工测试和修复bug的压力就增加了。最终,从某个时候开始,团队将花费一半或更多的时间来测试和修复bug。然而,敏捷团队应该关注的是交付有价值的东西。

 

避免bug的产生才是关键

Philip Crosby在他的”Quality is free” 摘要里写着“阻止缺陷的产生往往更有效”。这被很好地应用到软件开发中了。下图能很好地说明这点—它着眼于软件和其他行业中bug的开销。

修复bug需要的时间,单位:分钟

scrumcn1387173805

 

Backlog整理阶段:在这个阶段,开发者通过问PO问题来证实或消除他们的一些假设。通过对需求的详细讨论,一些错误理解会被消除,一些可能出现的bug也被避免了。这个阶段,消除bug需要的时间是最少的,因为一行代码都还没写呢。

 

微测试阶段:当修改代码引起了微测试失败,失败的测试能被明确地定位到某个开发者。因为测试频繁地运行,从最后一次测试通过到测试失败修改的代码很少,开发者能很快地(通常在几分钟之内)修复bug。请注意,我使用的是“微测试”而不是“单元测试”,因为单元测试没有充分地强调它的小。

 

集成测试阶段:若微测试没有发现某个bug的话,那么这个bug会一直存在于系统中只到后面的测试能发现它。当在集成测试阶段发现bug的话,bug会涉及到更多的开发者做的变更。所以,需要多一点点的时间来定位出错的代码,也许需要其他开发者花费些力气来解决它。基于集成测试是定期运行的,开发者依然能回想起是哪些变更导致的bug,这可能需要1个小时或稍微少点的时间来处理。

 

人工验收测试阶段:当自动测试没有捕获到这个bug时,我们期望能通过人工测试来捕获。通常,当一个用户故事完成时我们会做人工测试,坏点的情况是,在发布正式版本前才做。这是距离开发它时已经过了几个礼拜或几个月了,而且通常会用缺陷管理系统来管理bug,这都会带来额外的开销。因为PO需要理解bug带来的影响并给其进行优先级排序,质量工程师需要想办法重现bug,开发者要拼命地回想很久以前做的变更。在这个阶段,相关人员为消除bug要花费的所有人力可能会达到几个小时到1天。

 

幸存的bug:剩下的没被发现的bug将被发布到正式环境面对最终用户。假如用户因此觉得到你的产品质量低劣,这就会给你的品牌带来负面影响,而且也可能会考虑其他的替代产品。修复线上产品的bug意味着要么在下个版本中修复(你的用户会一直经历不好的体验直到下个版本),或者,假如bug比较严重的话,会出一个补丁版本这会带来额外的开销。

 

Bug是随代码而生吗?

你有没有进过一个改了1礼拜bug或更长时间bug的团队的办公室?那里充满了负能量,接近崩溃的开发者要么正盯着调试器,要么正在抱怨这些bug报告都是活见鬼。这当然不是他们工作中最享受的时刻,特别是当火急火燎的PO在旁边晃来晃去催着出版本时。“bug是代码与生俱来的东西”常听到这个说法。“不,是你没做好你的工作”我说。那恰巧是系统中存在bug的原因。应该利用工具把Bug回避掉,当然也要选用合适的软件技术。

 

“修复Bug的开销 vs  bug存在的时间”图示清楚地表明在微测试和集成测试上进行时间投资是值得的。现在投资少量的时间可以节省更多的时间你不用再无休止地调试那些早已遗忘的代码变更和辨别bug报告中的误解。加上测试吧,规避风险。

 

那我们怎么开始呢?

很显然,为所有代码编写测试用例是没有商业价值的,因为在给最终客户提供有价值的产品之前往往要花费数月的时间。当团队看到自动化测试带来的曙光时到底该怎么做呢?像小鸡过马路一样一步一步地来。假如你在项目开始时没有引入自动化测试,那么从现在开始吧。利用上文中内容来说服PO(希望你不必说服SM),并且重新给完成下定义。

关于完成的定义的一些补充

l  每个新的用户故事都要被微测试覆盖到

l  每个新的用户故事都要被自动化集成测试覆盖到

l  在后期发现的新bug都要被微测试和自动化集成测试覆盖到

构建自动化测试环境需要初始投资,设置好最开始的几个测试可能会花些时间。所以要制定现实一点的目标。比如,先拿一个用户故事做试验,你作为起始的那个sprint的速率会下降,没有产出交付物,这仅仅会让那些不认可此方法的人气焰嚣张。你不要因此而沮丧,慢慢来并开始享受这个过程吧。除了写代码和利用写代理来阻止bug摒弃调试工具更让开发者更喜爱的呢?开始爱上微测试全部通过时的那个绿条吧!

 

改变观念:停止生产线

一旦我们开始往系统中引入bug,测试就会失败,这是个好事情。想象一下,如果bug在后来的阶段中不被测试覆盖到会是什么情况?在老的工作方式下,bug将会被录入bug管理系统,而且在我们开始修复它们之前,它们必须被清晰地描述出来,并且需要质量工程师和PO的评审。现在需要开发者转变观念,失败的测试一旦被发现就应立即修复,越快越好。停止生产线是一项精益实践,来自于丰田生产系统,当发现缺陷时他们会停止生产线以避免生产出缺陷产品(这意味着浪费)。同理,在软件开发中,我们需要停止生产更多的代码,并修复失败的测试,否则,我们向有缺陷的代码中增加更多的代码的话,会增加我们修复bug的时间(这也是浪费)。当团队使用了持续集成工具,但是好几天都没有生成一个成功的构建,这就违背了增加这些测试的用意。如果每个小变更都被验证过了,那么每个失败的测试仅仅会影响到几行代码,这能被很快修复。

 

覆盖率

当你刚开始着手自动化测试时,你要阻止的bug数量是有限的,因为仅有一小部分代码被微测试和集成测试覆盖到了。因此系统里的一些bug只能在后期被发现。靠谱的做法是先加上能捕获到这些bug的测试,再修复bug;让你的测试现在就通过。这是辨别是否要增加新的测试有效方法,因为有bug出现就表明现有的测试没有捕获到它。假如你遵循新的完成的定义,那么覆盖率将持续增加,你生成的自动化构建质量也会提升,而且你也会发现你在调试和讨论bug报告的细节上节省了不少时间。

 

价值

开发者,质量工程师和PO花费更少的时间在bug修复和bug管理上了,他们就有更多的时间用在为最终用户交付价值上。开发者能写更多的代码,质量工程师能有更多精力关注测试场景和探索性测试,PO有更多时间思考新特性。更不用提你会有更开心的客户和更快的release版本了,而且你们会更具竞争力。

 

真的没有借口推迟自动化测试了。现在就开始吧!

 

原文地址:http://www.scrumalliance.org/community/articles/2013/january/quality-is-free