用Visual Studio实践敏捷测试(三)上
在上一篇中,我们讨论了敏捷开发流程中的一些由手动执行的测试任务。手动测试是需要人工完成的测试,被广泛应用于各类产品的各种测试任务中,而与之相对应还有自动化测试,即通过程序自动运行完成测试任务。自动化测试能帮助开发团队节省测试运行的人工、提高开发效率。接下来在本篇中,我想和大家讨论一下敏捷开发中手动测试和自动化测试之间的关系以及如何实现和利用自动化测试。
手动测试的特点
由于手动测试依赖于人工操作,很自然的存在着不确定性,每一次的操作都可能或多或少有一些不同。这种不确定性既是手动测试的优点,也为其带来了一定的局限性。从优点的角度来说,手动测试更加灵活多变,可能在不经意间就采用了一种全新的操作序列,或者将产品带入一个意料之外的状态。这有助于深入测试产品功能的细节,覆盖那些常规思路无法到达的用户场景。而从另一个角度来看,手动测试的不确定性也使得其测试覆盖的内容无法预料,在需要保障测试的覆盖面时,就显得有些不足了。此外,手动测试也不适应于大规模、大数据量、长时间或者是多平台的测试,人工完成这样大的工作量是困难且没有必要的。
手动测试的这些特点就导致其适用于那些允许灵活甚至是要求灵活的小规模的测试任务,比如伙伴测试就是个很好的例子——测试内容不那么死板,期望测试执行人有一些创造性。
自动化测试
自动化测试充分利用了计算机“任劳任怨”执行人类给它的指示的特点,用程序实现需要的测试,此后该测试就可以被多次自动执行。在测试会被大量运行的前提下,这不仅能节省重复人工劳动,更重要的是提供了一种迅速而准确的保证测试覆盖的方法。特别是在敏捷开发紧张的节奏下,自动化测试的这些特质能起到十分显著的加快开发进程的作用。
那么什么样的测试需要自动化呢?
最显然的是诸如压力测试等需要大量操作的测试场景。比如我们常常要求产品能承受连续8个小时以上的各种操作,这样大强度的压力测试并不适合人由工完成,显然自动化测试能更好的完成该项任务。
接下来是那些核心的功能和主要的用户场景,这些是产品最需要保护的部分,所以我们希望能在代码改变的情况下及时地运行相关的测试,以保证它们不被破坏。在敏捷开发高速运转、频繁签入的状态下,自动化这些测试以便能将其在封闭签入(Gated check-in)等测试运行中迅速自动执行、及时发现问题,能在很大程度上保证产品开发流程的顺利进行。同时,将这些重要的测试自动化也能避免手动测试的“偷工减料”问题,计算机总是会忠实的执行每一个测试步骤的。
此外还有一些从其本身特性而言不适合手动执行的特殊类型的测试,比如模糊测试(Fuzzing Test)要求大量生成随机数据一一对产品试验,也是自动化测试能大展身手的地方。
自动化测试的度
在这里我想提醒大家的是测试的自动化的程度并不是越高越好。在我的开发团队中,我们曾经将测试计划中高达95%以上的测试都自动化。这样的带来的显著优势是自动的测试运行提供了很好的覆盖率,从而保证了各项功能都能保持正确工作。但是,也带来了一些问题:首先,编写自动化测试程序需要大量的时间,很多时候让程序自动操作执行产品功能特别是产品UI是件很困难的事情,需要大量的时间和精力来实现测试程序本身。其次,当产品功能变化时,修改测试还要花费额外的成本,不像手动测试那样随时都可以更改。另外,自动化测试还有一个容易被忽视却十分重要的问题——远离了用户体验。当测试被“傻瓜式”自动执行时,我们根本无法得知其相对应的用户场景的使用感。举个简单的例子,再不方便使用的功能如果只写一次程序我们多半是可以忍受的,但是如果要手动执行,恐怕三五次就会让人受不了了。所以把握手动测试和自动化测试的比例是颇值得研究的一个话题。
在意识到过量的自动化测试会使其从辅助开发的工具变为团队的负担和障碍之后,我们调整了自动化测试的策略,采取了一种渐进式添加自动化测试的方案。在产品生命周期的前期,功能快速的被添加且行为随时可能改变,此时对测试的需求偏向于尽可能迅速完成对新功能的测试,自动化测试所需的建立测试框架以及在功能改变时修改代码的代价在此时显得过于昂贵了,所以我们更倾向于做较多手动测试,只实现少量简单而核心的自动化测试。而随着产品功能的不断添加和趋于稳定,不再有大量的新功能需要测试,而更多的需要用于保护已有功能不被破坏的自动化测试,此时可以陆续添加测试计划中那些之前没有时间自动化的测试用例。在产品生命周期的末期,特别是产品将有多个版本时,准备全面的自动化测试覆盖以保护产品功能不被破坏则成为主要的测试任务之一。
林俊彦
软件测试开发工程师
本文精简版收录于《程序员》9月刊。