《持续交付 发布可靠软件的系统方法》读书笔记
很多项目只依靠手工的验收测试来验证软件是否满足它的功能需求和非功能需求。即使某些项目有一些自动化测试,但这些测试常常因无人维护或很少维护而过时,所以还是需要大量的手工测试作为补充。测试是跨职能部门的活动,是整个团队的责任,应该从项目一开始就一直做测试,从一开始就将质量内嵌于产品之中。质量内嵌是指从多个层次(单元、组件和验收)上写自动化测试,并将其作为部署流水线的一部分来执行,即每次应用程序的代码、配置或环境以及运行时所需软件发生变化时,都要执行一次。手工测试也是质量内嵌的关键组成部分,如演示、可用性测试和探索性测试在整个项目过程中都应该持之以恒地做下去。质量内嵌还意味着,你要不断地改进自动化测试策略。测试策略的设计主要是识别和评估项目风险的优先级,以及决定采用哪些行动来缓解风险的一个过程。好的测试策略会带来很多积极作用。测试会建立我们的信心,使我们相信软件可按预期正常运行。也就是说,软件的缺陷较少,技术支持所需的成本较低,客户认可度较高。测试还为开发流程提供了一种约束机制,鼓励团队采用一些好的开发实践。一个全面的自动化测试套件甚至可以提供最完整和最及时的应用软件说明文档,这个文档不仅是说明系统应该如何运行的需求规范,还能证明这个软件系统的确是按照需求来运行的。
测试的分类
业务导向且支持开发过程的测试
自动的 - 功能验收测试
技术导向且支持开发过程的测试
自动的 - 单元测试、集成测试、系统测试
业务导向且评价项目的测试
手工的 - 演示、易用性测试、探索性测试
技术导向且评价项目的测试
自动的/手工的 - 非功能性验收测试,包括容量测试、安全性测试等
现实中的情况与应对策略
新项目
新项目有机会实现所描述的理想国,最重要的事情就是一开始就要写自动化验收测试。为了能做到这一点,你需要:
- 选择技术平台和测试工具;
- 建立一个简单的自动化构建;
- 制定遵守INVEST原则[即独立的(Independent)、可协商的(Negotiable)、有价值的(Valuable)、可估计的(Estimable)、小的(Small)且可测试的(Testable)]的用户故事[ddVMFH]及考虑其验收条件;
然后就可以严格遵守下面的流程:
- 客户、分析师和测试人员定义验收条件;
- 测试人员和开发人员一起基于验收条件实现验收测试的自动化;
- 开发人员编码来满足验收条件;
- 只要有自动化测试失败,无论是单元测试、组件测试还是验收测试,开发人员都应该把它定为高优先级并修复它。
遵守我们所说的流程,会改变开发人员写代码的方式。同后补验收测试的项目相比,那些从一开始就使用了自动化验收测试的代码库一般总是有更好的封装、更清晰的表达、更清楚的职责分离和更多的代码重用。这的确是一个良性循环:在正确的时机写测试会产出更好的代码。
项目进行中
引入自动化测试最好的方式是选择应用程序中那些最常见、最重要且高价值的用例为起点。这就需要与客户沟通,以便清楚地识别真正的业务价值是什么,然后使用测试来做回归,以防止功能被破坏。
遗留系统
在这种情况下,如果没有自动化构建流程,那么最高优先级的事儿就是创建一个,然后再创建更多的自动化功能测试来丰富它。如果有文档,或能够找到那些曾经或正工作在这个系统之上的成员的话,创建自动化测试套件会更容易一些。然而现实往往并非如此。项目的出资人(sponsor)并不愿意让开发团队把时间花费在一些看上去低价值的活动上,比如为已经在生产环境中使用的功能创建测试。他们会问:“这些功能不是已经在之前被QA团队验证过了吗?”因此,一定要聚焦于系统中高价值的功能。向客户解释一下,创建回归测试套件的价值在于保护系统当前的功能,这样就很容易啦。坐下来与用户一起识别系统中高价值的功能是非常重要的。利用前面一节所说的技术,创建一套广泛的自动化测试,覆盖这些高价值的核心功能。当然,我们不该在这上面花太长时间,因为这只是一个保护已有功能的框架。有了这个测试套件之后,就要逐渐为新增功能添加相应的测试。对于遗留系统来说,这些覆盖核心功能的测试就是非常重要的冒烟测试了。
集成测试
假如你的应用程序需要通过一系列不同的协议与各种外部系统进行交互,或者它由很多松散耦合的模块组成,而模块之间还有很复杂的交互操作的话,集成测试就非常重要了。我们所说的“集成测试”是指那些确保系统的每个独立部分都能够正确作用于其依赖的那些服务的测试。我们要确保在正式部署到生产环境之前,应用程序不要与真实的外部系统进行交互,否则就要想办法告诉外部系统,这个应用程序所发送的数据只是用于测试的。一般来说,有两种常见的方法来保证你可以安全地测试自己开发的应用程序,而不必与真正的外部系统进行交互,而且通常要同时使用这两种方法。
- 在测试环境中使用一个“防火墙”将该应用程序与外部系统隔离开来,而在开 发过程中,越早这么做越好。当外部系统不可用时,这也是测试应用程序行为 的一个好方法。
- 在应用程序中使用一组配置信息,让其与外部系统的模拟版本进行交互。
流程
在每个迭代开始时,召集所有的项目干系人开个会。假如没有做迭代式开发,那么就在某个用户故事开始开发的前一周召开这样的会议。让客户、分析人员、测试人员坐在一起,找到最高优先级的测试场景。测试人员和开发人员在开发前应该尽早一起讨论这些验收测试。这会让开发人员更好地了解用户故事,并理解最重要的场景是什么样的。与开发完用户故事之后再沟通相比,这会大大减少开发人员和测试人员之间的反馈循环,有助于减小遗漏功能的几率,并有助于减少缺陷。
管理待修复缺陷列表
理想情况下,你的应用程序根本不应该有缺陷。如果使用测试驱动开发和持续集成,并有一个全面的自动化测试集,其中包括系统级别的验收测试,以及单元测试和组件测试,在测试人员和用户发现缺陷之前,开发人员就应该能够捕获它们。然而探索性测试、演示以及用户使用的过程中,都可能会发现应用程序的缺陷,这也许是不可避免的。这些缺陷都会放在待修复缺陷列表(backlog)中。我们可以把缺陷分为严重(critical)、阻塞(blocker)、中(medium)和低(low)四个级别。根据这种分类方式,就能在待修复缺陷列表中根据优先级将缺陷与用户故事按相同方式来排序,并可将二者一起放置。
小结
在很多项目中,测试被认为是一个由一些专职人员负责的独立阶段。可是,只有当测试成为与软件交付相关的每个人的责任,并从项目一开始就被引入并持续进行时,才能产生高质量的软件。测试主要是建立反馈环,而这个反馈环会驱动开发、设计和发布等活动。将测试推迟到项目后期的计划最终都会失败,因为它破坏了产生高质量、高生产率,以及(最重要的)反映项目进展情况的反馈环。如果每次修改后都能运行一次自动化测试集合,就能建立最短的反馈环。