组织敏捷测试
在这篇文章中,我们将围绕测试组如何在组织中组织敏捷测试这个话题来展开讨论。
传统的软件测试有非常明确的测试阶段划分和测试过程定义,按照时间顺序开展每个阶段的测试,以及按照时间顺序组织每个阶段的测试构成了传统测试的主要组织方式。按照传统的软件测试阶段划分,软件测试可以在时间序上被分为单元、集成、系统与用户验收测试,分别对应软件的编码、设计与需求阶段。这种按照时间顺序的测试阶段划分对传统软件开发而言非常适用:测试的每个阶段用于对开发相应阶段的产出进行校验和确认,阶段之间通过固定的输入(通常以文档体现)和输出(例如测试报告)进行衔接。而传统的软件测试过程则一般被定义成测试需求、测试计划、测试设计、测试执行与测试评估总结这五个时间序的步骤,用以指导每个阶段中的测试。
在传统的软件开发模式中,这种明确的测试阶段划分和测试过程定义工作得非常好,但在敏捷的环境中,这种模式受到了很大的挑战。挑战首先在于测试阶段的划分上,敏捷测试鼓励为产品建立各层面的验证体系,从某种程度上来说,也可以将其对应到单元测试(代码级别的测试)、集成测试(接口与服务测试)、系统测试(UI级别的测试、系统性能测试等)以及用户验收测试(接受测试)上,但在敏捷环境下,各测试阶段间严格的时间顺序不复存在,敏捷开发鼓励并行,因此在一个敏捷项目中,单元、集成和系统等测试在时间顺序上通常是同时发生的。
其次,挑战来自于敏捷中所采纳的方法:TDD、BDD和ATDD等技术的应用使得敏捷环境中的测试成为了超越验证和确认开发阶段产出的存在,测试一方面是验证和确认,另一方面是设计。在这种情况下,一定要将测试划分为时间序上的测试阶段是非常不合理的。因此,在敏捷测试中,我倾向于抛弃单元测试、集成测试与系统测试的概念,而代之以代码测试、服务/接口测试、系统测试 —— 后者突出的是测试的对象,而非阶段。总而言之,在敏捷测试范围内,我们不需要过多的关心什么类型的测试应该在什么时候发生,而是始终秉承设置尽可能多的不同层次的测试的理念,在整个开发过程中为产品设置尽可能多的测试。
相较于传统软件测试的测试过程而言,敏捷中的测试并不特别注重过程,但这并非意味着敏捷测试不需要过程的控制。实际上,如果考察敏捷开发的一个迭代,在一个迭代中发生的测试与传统软件测试在过程管理上还是有诸多类似之处的。通常一个迭代中的测试目标相对固定:针对迭代定义的新功能的验证、针对原有功能的验证、以及保证开发过程中的持续的开发质量。与传统的软件测试相比,在验证方面,敏捷测试的一个迭代的测试目标与其基本一致;另一方面,由于测试执行活动仍然需要依赖计划、用例等,对传统软件测试的过程稍加修改就可以将其应用在每个迭代的测试活动中。我建议在一个迭代中,针对验证目标的测试仍然按照测试需求、测试计划、测试设计与执行、以及测试评估总结的过程方式来管理,但是由于敏捷测试本身的特性(迭代周期短,因而每个迭代中新增内容的验证不多;大量依赖自动化测试;依赖沟通而非文档等),在具体的操作上有一些区别。以下是本人建议的在一个迭代中针对验证与确认工作的测试流程:
- 测试需求
- 测试计划
- 测试设计与执行
- 测试评估总结
收集和整理本迭代中的所有需求(主要体现为新增功能和原有功能的修改),建议以在线文档(例如google的google docs)的方式管理每个迭代中的需求变化。通常需要对来自产品的需求进行一定程度的细化,细化到本产品的测试工程师能够清楚理解需要验证的点即可。测试需求通常需要与产品负责人和开发组确认(非正式评审)。
一页纸(One Page)的测试计划是一个很好的实践。测试计划中只需要包含本次迭代的目标,以及简单的时间和资源计划即可。
敏捷测试中的测试设计与执行通常是交织在一起的,对于新功能,测试工程师通常通过对新功能的使用和尝试来了解之,然后为其设计测试用例并用脚本(手工测试用例或自动化脚本)的方式将其固定下来;而对于原有功能的测试主要依靠自动化测试来进行。在测试设计阶段,测试工程师需要维护验收测试,以保证其准确地反映了每个迭代的目标。推荐使用在线表格或是轻量的用例管理软件对用例进行管理,在自动化程度比较高的情况下,甚至可以直接依赖测试需求列表和自动化测试脚本,而无需创建手工用例集合。
测试评估总结意味着对每个迭代中进行的测试进行评估与总结。与传统的测试相同,敏捷测试中评估的主要目的同样是获得被测产品质量与测试质量的度量,但在具体方法上与传统软件测试有一定的差别。
在系统测试层面上,在传统的软件测试中,我们通常定义从测试需求到测试用例的跟踪矩阵,基于这个矩阵计算测试覆盖率,据此获得测试质量度量,但在敏捷测试中,一方面,敏捷测试并不鼓励建立完整的从测试需求到测试用例的跟踪矩阵,因此很难的到一个精确的测试覆盖度量;另一方面,敏捷测试大量使用探索性测试的方法,由于探索性测试在覆盖方面的随意性,也很难准确度量得到覆盖率。
因此,我倾向于通过保证验收测试的完备性和在更低层次衡量测试覆盖率作为测试质量评估的标准。由于一个迭代的周期很短,因此一个迭代中能够被添加和修改的功能较少,在这种情况下,维护完备的验收测试应该不是非常困难;而在更底层的测试中,通过接口或是代码覆盖率来衡量已建立的测试的完备性是更合理的方式。
对于被测产品的质量评估则完全依靠为产品建立的各种不同层次的测试。与传统软件测试相比,敏捷测试有两个主要的不同:首先,敏捷测试中的质量评估遍布整个开发过程,代码评审、持续集成、开发测试、接口测试等各种测试遍布在整个开发过程中,通过这些评审和测试,能够在各个维度上建立针对产品的质量评估;其次,敏捷测试通常非常看重产品的可测试性,因此,在整个质量评估体系中,对产品可测试性的评估是一个不能被忽略的因素。对产品可测试性的评估通过代码评审、代码测试覆盖率(通常具有好的可测试性的代码更容易达到更高的测试覆盖率)或是使用其他相关工具进行评估。
敏捷中的测试总结工作则主要是收集整理各次迭代中可复用的测试资源,从探索性测试中总结发现缺陷的模式,以及从缺陷分析中获得预防缺陷的信息。
当然,除了在每个迭代中针对迭代的目标建立和执行测试外,敏捷测试还意味着对产品质量和生产率的不断促进和提升。我个人倾向于使用任务列表来描述敏捷测试中的相关任务:
- 建立和维护持续集成,建立基于持续集成的质量控制和发布规则
- 持续改进产品的自动化测试框架,提高自动化测试的稳定性,降低自动化测试成本,不断提高测试覆盖率
- 发现值得关注的测试切入点
- 持续推动可测试性的提高
- 通过缺陷成因分析获得避免缺陷的信息,设立规则和实践避免缺陷引入
- 提高探索性测试应用能力,通过探索性测试发现更多的缺陷
- 创建更高效的工具,尽量将测试推动到上游
围绕提高生产率和提高质量这两个目标,敏捷测试是一个持续的自改进过程,这就意味着敏捷测试中的测试工程师必须采用与传统测试中不同的方式,持不同的测试理念和对待测试的态度。敏捷测试并非是一个面向过程的活动,一言以蔽之,在敏捷测试中,我们需要尽一切可能去考虑、去推动生产率的提高和质量的提升,将目光从单纯的关注发现缺陷本身移出来,去发现更多、更远、更有价值的需要去推动的事情。
关于作者
段念:Google中国高级测试经理,毕业于华中科技大学,先后在通讯、嵌入式软件、互联网等多个行业的国内外知名公司中从事软件开发与测试工作。对软件测试中的技术和管理工作有独到见解,对软件测试团队管理、自动化测试、性能测试与开发测试有较多研究。