《持续交付 发布可靠软件的系统方法》读书笔记

对于大多数项目来说,采纳持续集成实践是向 高效率高质量 迈进的一大步。

它保证那些创建大型复杂系统的团队具有高度的自信心和控制力。一旦代码提交引入了问题,持续集成就能为我们提供快速的反馈,从而确保我们作为一个团队所开发的软件是可以正常工作的。它主要关注于代码是否可以编译成功以及是否可通过单元测试和验收测试。

实现端到端的自动化构建、部署、测试和发布流程,就能很快建立一个相当成熟且能快速运行的构建、测试和部署系统。在交付项目里,这种端到端的部署流水线系统使我们获得了一定程度的自由和灵活性。我们确信,这种方法能让我们以更高的质量和相当低的成本与风险来创建、测试、部署复杂系统。

什么是部署流水线

部署流水线是指软件从版本控制库到用户手中这一过程的自动化表现形式。

流水线的输入是版本控制中的某个具体版本。每次变更都会生成一次构建,这个构建像神话中的英雄一样,闯过一系列的测试,希望成为一个能到达生成环境中的发布版本。在这一系列的测试阶段中,每个阶段都从不同的角度评估这个构建版本,且和持续集成一样,它的起点是向版本控制库的每一次提交。

一般来说,只要某个构建使无论是这一流程中的哪个阶段失败了,它都不会进入下一个阶段。

部署流水线的相关实践

  • 只生成一次二进制包;
  • 对不同环境采用同一部署方式;
  • 对部署进行冒烟测试;
  • 向生产环境的副本中部署;
  • 每次变更都要立即在流水线中传递;
  • 只要有环节失败,就停止整个流水线;

    提交阶段

    每次提交都生成部署流水线的一个新实例。如果提交阶段的测试通过了,这个版本就被视为一个候选发布版本。

在提交阶段,我们需要做以下几件事:

  • 编译代码(如果所用开发语言需要的话);
  • 运行一套提交测试;
  • 为后续阶段创建二进制包;
  • 执行代码分析来检查代码的健康状况;
  • 为后续阶段做准备工作,比如准备一下后续测试所用的数据库;

    自动化验收测试之门

    部署流水线中的自动化验收测试阶段与功能验收测试之间的关系,和提交阶段与单元测试的关系相似。

验收测试阶段的目标是断言应用程序交付了客户期望的价值,并满足了验收条件。它也是一个回归测试套件,用于验证新的修改是否在现有功能中引入了回归缺陷。

验收测试一旦失败,开发团队就必须立即对其作出响应。

后续的测试阶段

对于很多系统来说,即使有非常全面的自动化测试集合,在发布之前,仍需要某种形式的手工测试。

另外,很多项目还需要有不同的环境来做与其他系统的集成测试,还需要测试容量的环境、做探索性测试的环境以及试运行和生产环境。每个环境多多少少都会与生产环境有些相似,并且有特定于它自己的配置信息。

手工测试

在迭代开发过程中,验收测试之后一定会有一些手工的探索性测试、易用性测试和演示。

测试人员会做一些机器不太擅长而人比较擅长的测试。他们做探索性测试、易用性测试,在不同平台上测试程序的界面是否正确,并着眼于一些不可控制的最坏情况进行测试。

自动化验收测试使测试人员节省出更多的时间做那些高价值的活动,而不是测试脚本的人力执行器。

非功能测试

每个系统都有很多非功能需求。比如,几乎每个系统都有容量和安全性方面的要求,或者必须遵守服务水平协议等。通常应该用某些自动化测试衡量应用程序是否满足这些需求。

发布准备

每次向生产环境发布时都有业务风险。缓解这类风险非常简单,只要把这个发布环节视为部署流水线的一个自然结果就行。实际上,我们只需要:

  • 让参与项目交付过程的人共同创建并维护一个发布计划(包括开发人员和测试人员,以及运维人员,基础设施和支持人员);
  • 通过尽可能多的自动化过程最小化人为错误发生的可能性,并从最容易出错的环节开始实现自动化;
  • 在类生产环境中经常做发布流程演练,这样就可以对这个流程及其所使用的技术进行调试;
  • 如果事情并没有按计划执行,要有撤销某次发布的能力;
  • 作为升级和撤销过程的一部分,制定配置迁移和数据迁移的策略;

我们的目标是实现一个完全自动化的发布过程。发布就应该简单到这种程度,即只要选择一个需要发布的版本,单击一下按钮就万事大吉了。撤销也应该同样简单。

实现一个部署流水线

无论是从零创建新项目,还是想为已有的系统创建一个自动化的流水线,通常都应该使用增量方法来实现部署流水线。一般来说,步骤是这样的:

  • 对价值流建模,并创建一个可工作的简单框架;
  • 将构建和部署流程自动化;
  • 将单元测试和代码分析自动化;
  • 将验收测试自动化;
  • 将发布自动化;

    度量

    度量什么?选择什么样的度量项对团队行为有很大的影响。

尽管应用程序的周期时间是软件交付中最重要的度量项,但还有一些其他度量项可以对问题起到警报作用。

  • 自动化测试覆盖率。
  • 代码库的某些特征,比如重复代码量、圈复杂度、输入耦合度、输出耦合度、代码风格问题等。
  • 缺陷的数量。
  • 交付速度,即团队交付可工作、已测试过并可以使用的代码的速率。
  • 每天提交到版本控制库的次数。
  • 每天构建的次数。
  • 每天构建失败的次数。
  • 每次构建所花的时间,包括自动化测试的时间。

    小结

    部署流水线的目的是,让软件交付过程中的每个人都能够看到每个构建版本从提交到发布的整个过程。

    推荐阅读

  • 测试策略的实现

  • 持续集成
  • 《业务架构·应用架构·数据架构实战》