为什么测试?

自动化测试的目标是自信:对应用稳定性的自信,对新特性能如计划运行的自信。持续集成可以看作是一门学问,主要在于保持稳定性的同时加速变化。随着参与贡献的开发者越来越多,就越有必要进行稳定性的自动化测试。

本文主要描述的是如何在 Drupal.org 运行的时候进行自动化测试基础设施,而不是编写测试。更多 Drupal 开发测试的编写请看社区文档:

测试分类

DrupalCI 本质上是运行两个类型的测试:

功能测试 (也叫做黑盒测试) 是在 DrupalCI 硬件运行的最常见测试类型。这些测试运行断言,也就是功能测试,是通过安装 Drupal,新建一个全新的数据库,然后再插入数据和确认断言已完成。前端测试和行为驱动测试 (BDD) 倾向于功能测试。升级测试是功能测试的一种类型,运行一个 Drupal 的完整安装,然后执行升级命令。

单元测试 运行断言是测试一个代码单元,不要求数据库的安装。也就是说单元测试因为其架构执行的非常快,Drupal 8 比 Drupal 7 有更多的单元测试覆盖。

这些测试类型后期会分裂成更多的特定测试类型。

Drupal 的规模测试意味着什么?

Drupal 8 拥有 3000+ 核心贡献者,还有 7288 contrib 开发者(目前),测试的需求是可以轻松的推进代码发展,并且让每个人都信任 Drupal.org 的稳定性。

在 2016 年 1 月份到 6 月份,DrupalCI 触发运行了 90365 个测试,大概每个月运行了 18000 个测试。维护者可以设置任何他们想要运行的测试,包括每个分支的提交或者 nightly。而且维护者还可以决定他们测试运行的环境;提供 6 个 PHP 和数据库引擎给他们选择。

这个时期进行的大部分测试都是 Drupal 8 测试。 (这 5 月期间运行了 19,599 核心测试和 47,713 contrib 项目测试) 每个测试有大概 12% 在 Amazon Web Services 运行,社区每个月平均在测试上花费  $2,000。(感谢赞助商!)

Drupal 自动化测试历史概述

自动化测试第一次出现在 Drupal 贡献的项目是在 Drupal 4.5 版本的时候,引入了 SimpleTest 模块。直到 Drupal 6 我们就开始了手动构建 testbot,并且在 Drupal.org 硬件上运行这些测试。

在 Drupal 7,SimpleTest 已经成为了 Drupal Core。(更多详情请看 SimpleTest Roadmap for Drupal 7。)

在 Drupal 8,PHPUnit 测试添加到 Drupal Core。 PHPUnit 测试比 SimpleTest 中完整的功能测试更快 —— 虽然 runtest.sh 在 Drupal 8 仍然触发这些测试类型的结合。

自动化测试的实际实现比之前的更加复杂。原始的 testbot 基础设施已经在 Drupal.org 硬件运行了 7 年,通过一些志愿者手动管理。这些手工维护自然而然的就产生了 Drupal CI 架构,可以更简单的进行本地测试,并且可以进行非常强大的硬件自动规模测试,测试速度更快。

DrupalCI 的基础结构

The Drupal.org Complexity 中,可以知道 Drupal 代码基础库与系统其他部分错综复杂的交互。

Representation of the relationships between services and sites in the Drupal.org ecosystem.

我们可以进一步分析类似 DrupalCI 系统是如何互相关联的:
Highlighted relationships between testing and other services.

DrupalCI 是 Drupal.org 上数据存储的连接,计划作业,drush 命令和最重要的是一些 Jenkins 安装来管理所有的自动化。

Jenkins 是个开源的自动化服务器项目。DrupalCI 使用 Jenkins 来自动化构建进程,部署代码到 dev, stagin 和生产环境。 Jenkins 可以自动化所有东西,很多公司会用来运行持续集成或者持续开发。Jenkins 在 Travis,CircleCI,Bamboo 这些选项中被称为是“最佳实践”解决方案。这些选项都有不同的特性,但是自动化是这些 DevOps 工具的核心。

为了提供持续的集成测试,你需要在测试最大值的时候触发这些测试。

在分支被添加到 issue comment,代码提交到仓库的时候这三个触发器就会运行一个测试作业。维护者可以指定哪个触发器关联他们项目的分支,和哪个环境来运行这些测试。

核心设置类似:

Screenshot of the automated testing settings for Drupal Core.

这些详情可以让特定的测试在特定的时间运行 Drupal.org Testing Policy for DrupalCI

为了实现自动化,需要安装 Jenkins,通过每分钟一次查询 Drupal.org 的测试作业形成队列。

这些作业是 Drupal.org 的一个数据库记录:

The infrastructure jenkins instance polls Drupal.org once per minute looking for new jobs to queue.

基础设施 Jenkins 会与 CI Dispatcher (也是 Jenkins) 进行通讯,测试队列常规的会通过这些作业提供 testbots。当前如果没有现成的 testbot ,那么 CI Dispatcher 会使用一个Amazon Web Services EC2 插件来指定新的 testbot。这些容器从 DockerHub 仓库拉取,包括 Drupal 支持的,官方的 PHP 与数据引擎的连接。

The CI Dispatcher maintains the queue of jobs to run. When a job is ready, it uses an EC2 plugin to use an existing testbot or spin up a new bot as needed.

运行一个 testbot 之后,CI Dispatcher 会持续与 bots 通讯。你甚至可以在 CI Dispatcher 点击到工作台,查看测试的运行情况。 (这看起来不是那么兴奋——也许该添加一些声音效果——这个非常方便。)

Once the testbot has been spun up, the CI Dispatcher listens to it for results.

一分钟一次,Drupal.org 查看 CI Dispatcher 的测试状态。CI Dispatcher 会响应等待,运行,失败或者通过。失败和通过测试会拉取回 Drupal.org,使用 Jenkins JSON API 显示。

 pending, running, failed, passed. All the results are pulled back into Drupal.org using the Jenkins' JSON API.

测试可以按照要求运行在 patch,commit或者 branch 级别,使用便捷的 “add test” 和 “retest” 链接。

为什么要亲自构建,而不是使用第三方持续集成工具

很多朋友问我们为什么不使用现有的 TravisCI, CircleCI 或者其他的测试解决方案。因为大部分公开提供的测试系统都要求 GitHub 身份认证与集成。

此外,我们的测试基础设施非常强大,因为集成了 issue 队列。更多详细内容请看 The Drupal.org Complexity

另外的原因是因为规模。 为了在可接受的时间内通过所有 Drupal 8 的所有核心测试(平均 44 分钟),运行非常大型的 testbots。这些 bots 有 2 个处理器,8 个硬件核心。因为超线程,意味着有 32 个硬件执行线程 —— 大约 88 EC2 计算单元。这还不是超级电脑,但是他们拥有非常高的性能。

平均每个月运行 18000 个测试。在最高峰时期达到 25 个 testbot 机器,虽然平时只能保证 15 个 bots。

我们已经在探索使用一个企业许可,不管是 GitHub 还是 CircleCI。这些考虑也会延伸到 SauceLabs 前端测试。现在,还没有一个节省开支的迁移方案,但不排除在未来会有所突破。测试服务在不断的改革发展。

加速 Drupal 8

2015 年初期,我们不断优化旧版的 testbots,把他们迁移到 AWS,使用更快的机器和更多的 bots。但是 Drupal CI 基础设施最关键的开发还是在 Drupal 8。

感谢 jthorson, ricardoamaro, nick_schuch, dasrecht, basicisntall, drumm, mikey_p, mixologic, hestenet, chx, mile23, alexpott, dawehner, Shyamala, 和 webchick

Drupal 的测试工作未来有何计划?

大部分未来的测试计划都提供在 Drupal.org Testing Policy for DrupalCI

关键的问题是我们仍然需要解决关于并发测试的改进,以及支持新的测试类型。在 test runner 中集成 PhantomJS,会有一定的优化效果。

测试并不是最后一个步骤,像其他的工作一样,都是为了通过提供改进测试的工具来持续的优化 Drupal。

更多内容请看 Drupal 博客

Drupal —— 维基百科

Drupal 是一个由Dries Buytaert创立的自由开源的内容管理系统,用PHP语言写成。在业界Drupal常被视为内容管理框架(CMF),而非一般意义上的内容管理系统(CMS)。

整套平台把所有内容视为一个“节点” (node),背后由大量“模块” (module) 控制其显示、修改、排列、分类等方式。这种设计令 Drupal 不只可以创建普通的博客网站,只要配合适当组件,控制内容显示及处理权限的方式,它马上能变成论坛、Wiki、社区网络。迄今(时间:2013年10月),Drupal的社区已编写了超过23,855个模块(module)。

Drupal 虽然配有强大功能,但不少用户批评其使用接口复杂、违反直觉、设置分布容易惹人混乱。2010年 Drupal 7 的测试版推出,接口引入 WordPress 的仪表板 (Dashboard) 元素,集中改善系统接口,但不少版型 (theme) 及模块 (module) 在当时仍未推出 7.0 版本配合。每次 Drupal 有重大更新时,不少旧的配件未能成功过渡,这也备受诟病。

然而,Drupal 的功能由于极具弹性,而且其运作环境能让编程人员较易作大幅改动,创建出大量崭新功能,令他备受欢迎。至2012年9月,全球约有 2.2% 的网站均由 Drupal 制作,使用内容管理系统中的 7%。