笔者所在敏捷团队及开发周期简介
团队组成:1位产品经理 + 7位开发人员 + 3位测试人员
开发周期:3个月
敏捷流程:1个开发周期 (Release)包含 4个迭代 (Iteration),每个迭代包含 3周 (Week),其中前两周为开发周,后一周为测试周。
本文笔者将从用户需求的理解、测试用例的管理、个体测试和整体测试,以及回归测试等几大方面具体阐述在敏捷开发模式下软件测试技巧;并在每部分的结尾处都加以小结,列出相关要点共读者参考。
用户需求的正确理解
对一名测试人员来讲,正确、全面的理解用户需求是极其重要的。(更多精彩内容请戳:敏捷项目的自动化测试策略)
只有真正理解了用户需求,才能站在用户的角度来看问题,想问题,并把这些思想应运到软件测试当中去,及时发现并纠正软件开发过程中的缺陷。
如果对用户需求一知半解,不能站在一个相当的高度看问题的话,测试人员就会为了测试而测试,迷失在繁多的测试案例之中。
更糟糕的是,如果测试人员 (其实对每位团队成员都一样)对需求理解不当,并且没有及时得到纠正,那么整个团队必将为此付出相当的代价。
在每个开发周期的开始阶段,笔者所在的团队所有成员会坐在一起讨论这个开发周期的开发需求并拟定相应的开发、测试计划。
一般来说,产品经理会主持会议,重点介绍接下来需要开发的新增功能模块(New Features)并且回答团队成员的相关问题。
对于测试人员来说,我们会充分利用这个机会向产品经理提出我们对需求的疑问,并交换各自的看法,其目的是为了更加准确无误的理解整个需求。
当然,在这个会议之前,我们需要花时间去了解这个开发周期的所有用户需求,做好准备工作。
另外开发人员和测试人员对用户需求理解的一致性也是相当重要的。坦白的讲,开发人员对用户需求的理解往往不是特别的到位 (当然这个不是绝对的) 。
这就要求我们测试人员提高警惕,需要经常和开发人员沟通、交流,以保证每位成员对需求的理解是一致的,当然前提必须是正确的理解。如果开发和测试对需求理解有分歧,最好是及时找到产品经理加以协调、解决。
有些时候,我们在测试的过程中会发现这样的缺陷,其本身并没有问题,但这不是用户想要的行为;究其原因就是开发人员在开发的过程中对需求的理解有所偏差。
为了避免这类软件缺陷的产生,我们必须保证团队的每位成员在实施软件开发之前都要正确的理解用户需求。
还有在敏捷开发过程中,用户需求的变更是很常见的。一旦这种情况发生,我们每位成员就要敏捷应对,重新认识、理解用户的用意,并做出相应的调整.
例如测试人员需要及时的更新测试用例,开发人员则要及时修改代码,以保证整个功能模块朝着用户期望的方向发展。
在这个过程中,我们同样需要开发人员和测试人员对变更后的需求有正确的、一致的理解。
小结
重视用户需求的正确理解,它是软件开发的重要基石。
确保团队成员对用户需求理解的一致性,避免因理解误差所引起的缺陷。
敏捷应对用户需求的变更,及时作出相应调整。
测试用例的创建和管理
对于测试人员来讲,在实施软件测试之前的一项重要工作就是测试用例的设计和编写。
在传统的开发模式 (例如瀑布模式)中,我们有足够的时间 (开发的编码周期长)来编写极其详尽的测试用例,并且这些用例一旦创建成功,我们就很少再去修改它了,在之后的测试当中我们会严格按照测试用例来挨个执行,对其依赖性很强。
然而在敏捷开发模式下,测试人员在每个迭代中要做的事情很多,我们用来编写测试用例的时间是有限的,而且更重要的一点是由于用户需求的变化,会导致我们测试用例的不断变更。
所以如何利用有限的时间来编写高效的测试用例是值得探讨的。
在笔者及其测试团队的实践中,我们会把较多的时间放在对用户需求的理解、沟通及测试本身。我们对于测试用例的依赖性并不是那么强,更多的是把它当作测试过程中的参考和指引。
所以在编写的过程中,我们会选择一些通用的、基础的、重要的用例,而摒弃那些重复的、繁杂的、生僻的用例,使得我们的测试用例看上去简洁明了但又突出重点。
这样就算用户需求有什么变化,测试用例改动的也很少,节省时间。当然,这么做的前提还是得要求测试人员有一定的测试经验和探索精神,在测试的过程中要有针对性的实施测试,并且在时间允许的情况下尽可能的覆盖更多的实际用例而不只是局限于我们创建好的测试用例。
另外,敏捷开发的新功能模块是细分成更小模块分散到各个迭代中去依次完成的,与之相对应,我们的测试用例也是分批创建而成的。
但是最后我们会把所有的测试用例整合在一起,形成一个完整的且符合逻辑的测试用例集合,用于以后对这个功能模块的回归测试。
这时候,如果每个迭代中的测试用例都简洁明了且突出重点,那就非常有利于我们的整合工作,也便于今后的管理和维护。
小结
敏捷模式对测试文档的依赖性较小,更加注重沟通交流。
测试用例的编写遵循简洁、明了、通用的原则。
个体测试 (Story Test)和整体测试 (Feature Test)
上一节提到在敏捷开发的过程中,我们会把整个功能模块 (Feature,笔者称之为“整体”)按照一定的业务逻辑分割成若干个更小的模块 ( Story,笔者称之为“个体”)加以开发。
开发人员会按计划完成分配到各个迭代中所有个体的编码工作,并按时交付给测试人员。笔者所在的敏捷团队中,我们会用两周时间进行开发,一周时间用来测试。
对于测试人员来讲,我们一旦拿到开发人员完成的个体,就得马上进入测试状态,尽早尽快地找出个体当中存在的缺陷和潜在问题,并且第一时间以缺陷报告的形式提交上去,让开发人员尽快修复。
由于个体之间的连续性及内在关联性,我们只有保证已完成的个体符合客户需求,没有明显的缺陷,才能在接下来的迭代中继续开发剩下的个体;否则话,我们带着个体缺陷前进,就会偏离正常轨道;
而且随着迭代的不断进行,风险会累积增加,等到最后再去修复会让我们付出成倍的代价。
所以说,要想得到一个期望的整体功能,我们就要认真仔细的对待每个个体测试,把可能的软件缺陷消灭在初始阶段。
当所有的个体都开发完成并通过测试,整体功能模块也就呈现出来了,但此时的整体并不一定能像我们所期望的那样正常工作,相反多数时候会暴露出很多的问题,而这些问题是个体测试中不曾出现的。
另外,性能问题也是在整体测试中经常出现的。这时对于测试人员来说是个不小的挑战,我们唯一可做的就是在较短的时间内对整体功能、性能进行彻底、系统的测试,尽可能多的找出潜伏在整体当中的软件缺陷。
由于时间的紧迫性 (整体功能完成一般已来到了软件开发的中后期) ,在团队资源允许的情况下,我们也会在这个时候增加人手对整体功能进行更加细致的测试,以保证整体功能的正确性和稳定性。
在敏捷开发中,一般来说用户的需求中会包含多个新增功能模块。很多情况下,这些功能模块是同时进行开发和测试的。
那么我们应该如何高效的分配测试资源和测试任务呢?根据笔者及其团队的经验,我们认为从软件个体测试和整体测试的角度来讲,每位测试人员负责一个固定的功能模块比多位测试人员共享多个功能模块更专注,更有效,更能保证其功能模块的质量。
例如在笔者的团队中,我们有 3位测试人员,如果在某个开发周期中整个团队要开发 5个新增功能模块,我们每位测试人员在一开始就会分配到 1~2个功能模块,然后每位测试人员就会对各自所要测试的模块全权负责,包括需求的理解,测试用例的创建,个体测试及整体测试等等。
这样做的好处在于测试的连贯性和完整性,而且还能培养每位人员独立担当的能力。当然,在某些情况下,我们也会重新分配资源进行交叉测试,例如在下一节提到的回归测试。
小结
尽快尽早的进入个体测试,挖掘其中的缺陷,为整体测试减少障碍。
彻底系统的进行整体测试,保证其整体功能的正确性及其性能的可接受性。
按照各人责任制原则,合理安排测试人员,同时完成多个功能模块的测试。
回归测试 (Regression Test)
敏捷开发由于其自身的特点,在整个开发周期中它留给测试人员做回归测试的时间并不充裕,并且随着软件产品的不断更新壮大,需要覆盖的回归测试用例也越来越多。
在这种情况下,想要彻底的、全面的实施回归测试似乎变得越来越困难。
笔者首先想到的办法是用自动化测试来支持回归测试,虽然我们现在还没有完全实现这个想法,但是我们已经着手做这件事情了,相信不久的将来,自动化测试会在回归测试中发挥重要作用,大大提高测试效率。
那么在没有实现自动化测试的情况下,怎么样更好的实行回归测试呢 (再说自动化测试也并不一定能覆盖所有的测试用例)?
笔者所在的团队是这样做的,为了尽早的发现产品的衰退问题,我们会在每个迭代的后期做一次快速的回归测试,重点是测试与新增功能相关的领域,覆盖一些基础且重要的测试用例。在这个回归测试中,我们会要求团队的每位成员都参与进来包括产品经理、开发人员和测试人员,每人每次大概花费 2小时,我们称之为团队回归测试。
由于每位成员看问题的角度不尽相同,我们在每次团队回归测试中都能发现不少问题,并且及时得到解决,使得整个产品在开发过程中衰退的风险大大降低。
测试人员集中的回归测试发生在所有新增功能模块开发结束并通过测试,且版本相对比较稳定的时候。
此时已来到软件开发的后期,留给测试人员做系统回归测试的时间相对有限。对此我们团队会开会讨论把所有的回归测试用例按优先等级划分成 P1、P2和 P3。
其中 P1是优先级最高的,它包含了一个 Feature最基本,最重要的 Use Case和 Workflow。
P2则是包含了一些常用的 Use Case,重要性仅次于 P1。
P3用例更多的是包含了一些功能的细节,重要性较低。
如果某个 P1用例测试失败,则整个功能模块就失败,那么整个产品也就失败,所以说 P1测试用例是必须第一时间覆盖到的。
只有保证所有的 P1用例通过测试,我们才进入 P2、P3用例的测试。同时我们也会加强一些重点领域的测试,例如与新增功能相关的区域往往是缺陷重灾区,我们会对此投入更多的测试资源和精力。
只有这样,我们才能提高敏捷模式下回归测试的效率和质量。
另外一点,为安全起见,在这个阶段回归测试发现的所有衰退,我们会要求开发人员首先在本地环境修复此类缺陷,然后只有通过测试人员的验证并确认其他相关领域也没有问题,才能提交修复后的代码,最后测试人员会在新版本再一次验证缺陷的修复情况。
这样做既可以降低因修复一个缺陷而引起新衰退的可能性,同时也有效地缩短了测试周期,要知道在产品发布前夕,对风险的控制是第一位的。
小结
自动化测试服务于回归测试。
在每个迭代中进行一次快速回归测试,减少产品衰退的风险。
在开发后期的系统回归测试中,划分测试用例的优先等级,提高测试效率。
对于衰退缺陷,要谨慎修复和测试,控制风险。
结束语
以上是笔者及其测试团队在敏捷开发各个阶段的一些最佳测试实践及其心得。当然,要保证软件质量,在开发测试过程中需要注意的细节还很多,而不仅仅局限于笔者所提及的这些。
同时软件质量的保证也不能仅仅依赖于测试人员,而是需要敏捷团队中每位成员的共同努力。