从这一讲开始,我们进入本专栏第 3 部分的学习,我将用 8 讲的内容来讲解如何构建强大的敏捷测试基础设施(Testing Infrastructure)。测试基础设施是指支持自动化测试运行、测试开发、测试管理以及与研发环境集成的综合性平台。敏捷测试离不开稳定、高效、准确的基础设施,以满足对于持续测试、持续反馈的需要;同时,持续集成、持续交付和 DevOps 环境必须实现和测试基础设施的无缝集成,才能够满足软件在各种环境中持续验证的需要。

下面我来讲讲持续集成和持续交付的概念。

CI、CD 概念

“持续集成”(Continuous Integration,CI)在 1996 年就被列入了极限编程的核心实践,到 2006 年 Martin Fowler 提出了比较完善的方法与实践。持续集成是一个软件开发实践,在开发过程中团队成员频繁地提交代码到集成环境,每次集成都通过自动化的构建和测试尽可能快地发现问题,让软件始终保持在一个可工作的状态。这里的可工作应该理解为软件可安装、可运行,基本功能可用,可以进一步开展测试。

图1 Martin Fowler 对持续集成的定义

“持续交付”(Continuous Delivery,CD)是对持续集成的延伸,更是敏捷宣言“拥抱变化胜于遵循计划”价值观的体现。CD 是指软件经过开发环境、测试环境、准生产环境里的持续验证,满足了客户需求和质量目标,成为可交付给客户的产品。持续交付也是研发团队以一种可持续的方式把软件产品交付给客户的能力。持续交付的下一步就是持续部署,通过自动化的方式实现软件在生产环境中的部署。

敏捷的目标

我们重温一下敏捷宣言 12 项原则的第一项:首要任务是尽早持续交付有价值的软件并让客户满意。因此可以说,敏捷的目标就是要做到持续交付,尽快向用户交付满足需要的、可工作的软件。产品或变更只有快速交付到客户手中才能实现价值,没有交付给客户的产品从业务角度上来说是没有价值的。持续交付以敏捷开发的快速迭代为基础,通过小批量的变更,以及持续集成、持续验证实现产品从研发到客户的快速流动。

Scrum 模式下每次迭代结束会提供一个可向客户交付的软件版本。如果企业的业务模式是 SaaS,也可以像前面介绍过的 Etsy 一样,实现一天几十次甚至更多次的线上部署。

倒推:CD 持续验证 CI 持续单元测试

那么,为了使软件达到可以交付,需要经过哪些过程呢?

产品要满足交付的标准,需具备两个条件:第一,满足用户预期和质量要求;第二,在生产环境中可以成功部署。

为了满足这两个条件,首先我们需要搭建和生产环境尽可能接近的测试环境或准生产环境(Stage Environment),然后部署流程在不同的目标环境中通过验证。在测试环境中不断对新增加的特性、新版本的软件进行持续测试,在准生产环境中通过验收测试和全面回归测试。在上述任何阶段发现问题要及时反馈、及时修复,这就是一个持续验证的过程。

而持续验证需要我们随时能得到一个可工作、可持续测试的新版本,这就是持续集成要做的事:首先代码编译后通过单元测试和代码审查以保证代码质量;然后部署到测试环境验证是否可运行并且基本功能可用。

代码在提交构建 / 集成之前,应该由开发人员在自己的开发环境里编写、调试,同时不断地进行单元测试,以保证新开发的代码包括新的修改总是满足需求,即符合用户故事的验收标准。

开发人员编写代码的依据是系统设计,包括架构设计、组件设计、界面设计等,因此持续编程 / 单元测试前一步应该是持续设计。

要让交付成为持续、快速的活动,往前推的每个步骤都应该在小批量更改的基础上进行持续、快速的自循环,并且通过每个步骤内建的测试活动让问题尽早发现在源头,并尽早得到修复。

图2 对持续交付流程的反推

重点:持续集成 + 持续测试

在第 4 讲,我从敏捷测试流程的角度讨论了持续集成和持续测试,今天我将进一步讲解 CI 加持续测试对于 CD 意味着什么。

代码的一次构建 / 集成大概包括以下活动:编译、测试、打包、部署和反馈。开发人员从提交代码变更触发构建,到收到反馈所需的时间最好控制在几分钟以内,否则会降低开发效率,并且这个过程应该是自动化的。

通过和自动化测试工具 / 框架的集成,CI 环境中可以执行几乎所有的自动化测试,但是一个必须要考虑的问题是,持续集成中测试覆盖面和提供快速反馈之间的平衡。一般来说,持续集成中的测试活动应该只包括单元测试、代码静态分析和 BVT(Build Verification Testing)。代码静态分析和 BVT 具体怎么做,我们很快会讲到。单元测试对外部系统的依赖少,运行时间通常在秒级,发现代码缺陷的成本低、效率高,研发团队应该对单元测试的代码覆盖率有比较高的要求,比如 80% 以上。

构建成功意味着所有的步骤都是成功的,所有的测试也是通过的,任何失败都会快速反馈给相关人员进行修复直到再次提交代码并且构建成功,而且持续集成不仅要验证软件本身是否可工作,还要验证软件在测试环境中是否可以安装成功且可运行。

持续集成保证我们随时获取可工作的软件并进一步开展深入测试。随着版本的不断更新,模块、功能、用户故事不断增加,我们需要不断测试新的代码、新的用户故事和新的功能,最后覆盖业务端到端的测试,并包括性能测试、安全测试等。通过这样的持续测试,软件产品持续的接近并最终满足交付的功能需求和质量目标。

持续测试还包括持续的回归测试,以自动化测试的形式持续验证新的代码和功能不会影响正常运行的原有代码和功能。在这个过程中,单元测试的数量在持续集成测试里也在不断地增加,将成为回归测试的重要组成部分。

现在不少公司还在采用每日构建(Daily Build,每天一个新版本)的方式,严格来说这不是持续集成,理想的持续集成是:开发人员提交代码就会触发自动构建,一天构建多次。如果每天构建一个新版本,则构建和测试可以放在夜里完成,在这种情况下对 CI 时间限制也没有那么苛刻,可以把更多的测试内容(脚本)加入构建过程中。

微软公司在上个世纪 80 年代开发 Office 产品时就开始使用每日构建这种工程实践,冒烟测试的概念也是微软提出来的。不过,微软从 2007 年就开始尝试敏捷转型,从 2014 年开始逐步将自己的 IT 系统迁移到自家的公有云 Azure 上,到 2017 年,超过 4000 多名 Windows 开发人员每天都要进行 1760+ 次构建,提交代码就会触发单元测试及集成测试的自动运行。

CI、CD 环境

下面我来讲讲持续集成和持续交付环境,为下一讲的主题“测试如何融入 CI、CD 环境”做准备。

图3 CI 环境基本构成示意图

良好的持续集成环境能够实现自动构建、自动部署、自动验证,自动反馈。因此,CI 环境需要强大的工具链支持,需要的工具可分为 8 类:代码管理工具、版本构建工具、CI 调度工具、自动部署工具、配置管理工具、代码静态分析工具、单元测试工具、版本验证(BVT)工具。图 4 列出了每一类中比较常用的几种工具。

图4 持续集成工具集

如果考虑其他运行在 CI 环境中的自动化测试,那可以集成的不同层次、不同类型的自动化测试框架和工具就更多了。这相当于 CI 环境向 CD 环境的扩展,在持续集成的基础上,为实现持续交付在 CD 环境开展更多的持续验证活动。

根据自动化测试金字塔(详细内容将在第 16 讲中介绍),自动化测试可以按照不同层次划分为单元测试、API 测试和 UI 测试:

单元测试框架包括 JUnit、CppUnit、Mocha、PyUnit 等;

API 测试工具包括 Cpyress、Karate、PostMan 及 Rest-Assured 等;

UI 测试框架包括 Selenium、支持 Groovy 语言的 Geb 等。

值得注意的是,近几年大家对 API 测试的兴趣一直在稳步增长,通过 API 绕过 UI 界面直接在业务层展开测试可以覆盖软件的功能、性能、稳定性等需求,比 UI 自动化测试维护成本低。根据 Smartbear 在 2017 年的调查显示中发现,80% 的参与调查者在使用 API 进行软件测试,而超过 50% 的 API 测试以自动化的形式进行,预计两年内会增加到接近 80%。

另外,我们也可以按功能测试、性能测试、安全测试等维度来分类,支持功能测试的自动化框架有 Selenium、Appium 等;性能测试的自动化框架有 JMeter、Gatling 等;安全测试的自动化框架有 Wapiti、OWASP ZAP 等。

验收测试的自动化框架推荐选择支持 ATDD、BDD 和需求实例化的测试框架,比如 RobotFramework、Cucumber 等。

总之,每一类测试都对应不同的自动化测试框架和工具,可以集成在 CI/CD 环境中,通过 CI 调度管理工具就可以发起不同层次和不同类型的自动化测试。

另外,CI/CD 环境里还包括 CI/CD 流水线, 尽量通过自动化的方式来完成软件从构建、部署、测试到发布的过程。CI/CD 流水线强调减少人为干预和交接、在所有环境上采用一致的、可重复的部署实践,不仅支持软件产品从左到右的快速流动,也支持从右到左的快速反馈。在这方面,Jenkins 2.x 提供的了pipeline 功能,它通过和 CI 工具链的集成,能够很好地支持 CI/CD 流水线的构建,如图 5 所示。

图5 CI/CD 流水线

最后,给你出一道思考题:你所在团队的 CI 活动是理想情况下的 CI 吗?测试有没有成为瓶颈?如果测试成为瓶颈,如何改进?欢迎留言讨论。

-– ### 精选评论 ##### **3676: > 我们采用双周迭代模式,没用scrum框架,也是走的提测,但测试实践已经应用ci/cd,根据老师概念,这算敏捷测试吗?有点困惑,流程没完全按敏捷走,实践都是敏捷的 ######     讲师回复: >     CI/CD 意味这持续集成和持续交付,如果有提测,就很难做到持续交付。提测的存在,也意味这开发与测试在一定程度上的分离,从这个角度来讲,违背了敏捷测试宣言和敏捷测试原则,所以不算彻底的敏捷开发。话说回来,没有绝对的判断敏捷真伪的标尺,也不应该拘泥于形式,关键是能不能高效高质的产出、持续交付价值。 ##### *洁: > 低调低调