精读《持续集成 vs 持续交付 vs 持续部署》

1、摘要

相信你们之前应该接触过持续集成(Continuous integration)持续交付(continuous delivery)持续发布(continuous deployment)的概念,下面咱们来讲说三者的差别以及团队如何入手 CI/CD。前端

做者:猫神。webpack

2、差别

2.1 CI 持续集成

开发者尽可能时时刻刻合并开发分支至主干分支。避免直到发布日才开始合并,掉入集成地狱。不管什么时候新分支集成至项目,持续集成能够自动化测试持续验证应用是否正常。git

2.2 CD 持续交付

持续交付是持续集成的扩展,能够保证稳定的发布产品新特性。这意味着基于自动化测试,你能够也能够一键自动化发布。理论上,持续交付能够决定是按天,按周,按双周发布产品。若是确实但愿可以享受持续交付的好处,那么应该尽快发布到新产品中。一旦出现问题时能尽早排除。github

2.3 CD 持续部署

持续部署是持续交付的下一步。经过这一步,每一个新特性都自动的部署到产品中。可是若是出现未经过的测试用例将会终止自动部署。持续部署能够加速用户反馈新特性,避免发布日带来的压力。开发能够着力于开发系统,开发结束后几分钟就能够触达到用户。web

3、协做

CI/CD 具体是个什么样的流程呢,以下图所示,差别仅在因而否自动部署。浏览器

<img src="https://img.alicdn.com/tfs/TB...; />安全

如今开发都讲究投入产出比,那么 CI/CD 具体须要作些什么呢?服务器

Continuous Intergretion 持续集成

投入:微信

  • 须要为每一个新特性编写测试用例
  • 须要搭建持续集成服务器,监控主干仓库,并自动运行测试用例
  • 开发须要尽可能频繁的合并分支,至少一天一次

产出:并发

  • 更少的 bug,由于自动化测试能够回归测试产品
  • 编译部署产品更简化,由于集成的问题都尽早的解决了
  • 开发者能够尽可能减小上下文切换,由于构建的时候就暴露问题,尽早解决了
  • 测试成本下降,由于 CI 服务器能够一秒运行几百个测试用例
  • 测试团队花更少的时间测试,能够重点关注测试上的改进。

Continuous delivery 持续交付

投入:

  • 须要有持续集成的基础,测试用例须要覆盖足够的代码
  • 部署须要自动化,用户只须要手动触发,剩余的部署应该自动化
  • 团队须要增长新特性标志,避免未完成的新特性进入待发布的产品
    产出:
  • 部署软件变得很是简单。团队不须要花费 n 天准备发布。
  • 能够提升发布频率,加速新特性触达用户进程。
  • 小的更改,对决策的压力要小得多,能够更快地迭代。

Continuous deployment 持续部署

投入:

  • 测试必需要作到足够。测试的质量将决定发布的质量。
  • 文档建设须要和产品部署保持同步。
  • 新特性的发布须要协调其余部门,包括售后支持&市场&推广等。
    产出:
  • 快速的发布节奏,由于每一个新特性一旦完成都会自动的发布给用户。
  • 发布风险下降,修复问题更容易,由于每次变动都是小步迭代发布。
  • 用户能够看到持续性的优化和质量提高,而不是非要等到按月,按季度,甚至按年

若是开发的是一个新项目,暂时尚未任何用户,那么每次提交代码后发布将会特别简单,能够随时随地发布。一旦产品开始开发后,就须要提升测试文化,并确保在构建应用程序时增长代码覆盖率。当您准备好面向用户发布时,您将有一个很是好的连续部署过程,在该过程当中,全部新的更改都将在自动发布到生产环境以前进行测试。

若是正在开发的是一个老系统,就须要放慢节奏,开始打造持续集成&持续交付。首先能够完成一些简单可自动化执行的单元测试,不须要考虑复杂的端到端的测试。另外,应该尽快尝试自动化部署,搭建能够自动化部署的临时环境。由于自动化部署,可让开发者去优化测试用例,而不是停下来联调发布。
一旦开始按日发布产品,咱们能够考虑持续部署,但必定要保证团队已经准备好这种方式,文档 & 售后支持 & 市场。这些步骤都须要加入到新产品发布节奏中,由于和用户直接打交道的是他们。

4、如何开始持续集成

4.1 了解测试类型

为了得到 CI 的全部好处,每次代码变动后,咱们须要自动运行测试用例。咱们须要在每一个分支运行测试用例,而不是仅仅在主干分支。这样能够最快速的找到问题,最小化问题影响面。
在初始阶段并不须要实现全部的测试类型。一开始能够以单元测试入手,随着时间扩展覆盖面。

  • 单元测试:范围很是小,验证每一个独立方法级别的操做。
  • 集成测试:保证模块间运行正常,包括多个模块、多个服务。
  • 验收测试:与集成测试相似,可是仅关注业务 case,而不是模块内部自己。
  • UI 测试:从用户的角度保证呈现正确运行。

并非全部的测试都是对等的,实际运行中能够作些取舍。

<img src="https://img.alicdn.com/tfs/TB...; />

单元测试实现起来既快成本又低,由于它们主要是对小代码块进行检查。另外一方面,UI 测试实施起来很复杂,运行起来很慢,由于它们一般须要启动一个完整的环境以及多个服务来模拟浏览器或移动行为。所以,实际状况可能但愿限制复杂的 UI 测试的数量,并依赖基础上良好的单元测试来快速构建,并尽快得到开发人员的反馈。

4.2 自动运行测试

要采用持续集成,您须要对推回到主分支的每一个变动运行测试。要作到这一点,您须要有一个服务来监视您的存储库,并听取对代码库的新推送。您能够从企业预置型解决方案和云端解决方案中进行选择。您须要考虑如下因素来选择服务器:

  • 代码托管在哪里?CI 服务能够访问您的代码库吗?您对代码的生存位置有特殊的限制吗?
  • 应用程序须要哪些操做系统和资源?应用程序环境是否受支持?能安装正确的依赖项来构建和测试软件吗?
  • 测试须要多少资源?一些云应用程序可能对您可使用的资源有限制。若是软件消耗大量资源,可能但愿将 CI 服务器宿主在防火墙后面。
  • 团队中有多少开发人员?当团队实践 CI 时,天天都会将许多更改推回到主存储库中。对于开发人员来讲,要得到快速的反馈,您须要减小构建的队列时间,而且您须要使用可以提供正确并发性的服务或服务器。
    在过去,一般须要安装一个独立的 CI 服务器,如 Bamboo 或 Jenkins,但如今您能够在云端找到更简单的解决方案。例如,若是您的代码托管在 BitBucket 云上,那么您可使用存储库中的 Pipelines 功能在每次推送时运行测试,而无需配置单独的服务器或构建代理,也无需限制并发性。
  • 使用代码覆盖率查找未测试的代码。一旦您采用了自动化测试,最好将它与一个测试覆盖工具结合起来,帮助了解测试套件覆盖了多少代码库。代码覆盖率定在 80%以上是很好的,但要注意不要将高覆盖率与良好的测试套件混淆。代码覆盖工具将帮助您找到未经测试的代码,但在一天结束的时候,测试的质量会产生影响。若是刚开始,不要急于得到代码库的 100%覆盖率,而是使用测试覆盖率工具来找出应用程序的关键部分,这些部分尚未测试并从那里开始。
  • 重构是一个添加测试的机会。若是您将要对应用程序进行重大更改,那么应该首先围绕可能受到影响的特性编写验收测试。这将为您提供一个安全网,以确保在重构代码或添加新功能后,原始行为不会受到影响。

5、接受 CI 文化

自动化测试是 CI 的关键,但同时也须要团队成员接受 CI 文化,并非心血来潮晒两天鱼,而且须要保证编译畅通无阻。QA 能够帮助团队建设测试文化。他们再也不须要手动测试应用程序的琐碎功能,如今他们能够投入更多的时间来提供支持开发人员的工具,并帮助他们采用正确的测试策略。一旦开始采用持续集成,QA 工程师将可以专一于使用更好的工具和数据集促进测试,并帮助开发人员提升编写更好代码的能力。

  • 尽早集成。若是很长时间不合并代码,代码冲突的风险就越高,代码冲突的范围就越广。若是发现某些分支会影响已经存在的分支,须要增长发布关闭标签,避免发布时两个分支冲突。
  • 保证编译时时刻刻畅通。一旦发现任何编译问题,马上修复,不然可能会带来更多的错误。测试套件须要尽快反馈测试结果,或者优先返回短期测试(单元测试)的结果,不然开发者可能就切换回开发了。一旦编译出错,须要通知给开发者,或者更进一步给出一个 dashboard,每一个人均可以在这里查看编译结果。
  • 把测试用例归入流程的一部分。确保每一个分支都有自动化测试用例。彷佛编写测试用例拖慢了项目节奏,可是它能够减小回归时间,减小每次迭代带来的 bug。并且每次测试经过后,将会很是有信息合并到主干分支,由于新增的内容不影响之前的功能。
  • 修 bug 的时候编写测试用例。把 bug 的每一个场景都编写成测试用例,避免再次出现。

6、集成测试 5 个步骤

  1. 从最严格的代码部分入手测试
  2. 搭建一个自动构建的服务自动运行测试用例,在每次提交代码后。
  3. 确保团队成员天天合并变动
  4. 代码出现问题及时修复
  5. 为每一个新实现的操做编写测试用例。
    可能看着很简单,可是要求团队可以真正落地。一开始你须要放慢发布的脚步,须要和 pd、用户沟通确保不上线没有测试用例的新功能。咱们的建议是从小处入手,经过简单的测试来适应新的例程,而后再着手实现更复杂更难管理的测试套件。

7、说说笔者的团队

以上文章主要是说明团队实现 CI/CD 的取舍和可行性步骤。下面来讲说但愿 CI/CD 给笔者团队带来什么样的变化。目前笔者团队已经实现前端项目发布编译工程化,采用的是基于 webpack 的自建工具云构建模式。但如今面临的问题是 1. 交互的系统比较多,交互系统提供的接入源变动后,须要人工通知其余系统手动触发编译,并且每次手动编译都须要在本地切换到指定分支,而后手动触发云构建,2. 多人协做,分支拆分较细,须要手动合并分支,触发编译。整个流程冗长,并且中间存在人力沟通成本,容易产生沟通偏差。因此首先但愿解决的是 CI 自动化,当依赖变动后或者分支合并后,自动集成,自动编译。固然生产环境暂时还不敢瞎搞,但大部分重复编译的工做量主要集中在预发环境,因此手动部署生产环境的成本仍是能够接受的。CI 自动化以前,须要提供系统之间交互的单元测试用例,每次 CI 后自动运行单元测试用例,最好能打通 QA 的测试用例,进行回归测试。流程对好比下:

<img src="https://img.alicdn.com/tfs/TB...;/>
能够看出引入CI后,咱们的成本是须要搭建CI服务器,新增单元测试、打通回归测试案例,但前者能够加快系统编译效率,后者能够进一步的提高代码质量,减小回归测试时间,这些成本都是能够接受的。市面上已有不少开源持续集成工具,例如咱们熟悉的Jenkins,还有TeamCity、Travis CI、GO CD、Bamboo、Gitlab CI、CircleCI……等等等等。目前还在继续调研中,这片文章应该会有第二篇,说说后续的实践和CD。

讨论地址是: 精读《持续集成 vs 持续交付 vs 持续部署》 · Issue #147 · dt-fe/weekly

若是你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。

关注 前端精读微信公众号

<img width=200 src="https://img.alicdn.com/tfs/TB...;>

special Sponsors

版权声明:自由转载-非商用-非衍生-保持署名( 创意共享 3.0 许可证
相关文章
相关标签/搜索