自动化 CSS 回归测试

Avatar of Garris Shipon
Garris Shipon

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费信用额度!

以下是 Garris Shipon 的客座文章。 我们之前已经讨论过 四种 CSS 测试类型。 回归测试是最困难的。 这种测试类型用于测试对 CSS 的更改是否会导致任何意外的视觉问题。 对于响应式设计来说,这更加困难。 Garris 在为大型网站构建新的响应式设计时,构建了一个用于执行此操作的工具。 在这里,他将带您完成整个过程。

本文最初发表于 2014 年 12 月。 现在已在 2016 年 4 月重新编写、更新并重新发布,因为这里介绍的主要工具 BackstopJS 已更新。

视觉回归测试用例

搜索“CSS 回归测试”,一个共同的主题变得清晰:破坏 CSS 很容易,测试它很难。

在我的一个大型在线零售商的响应式 CSS 重构项目开始时,情况就是这样。 与当时许多其他网络公司一样,我们正在为一个庞大的电子商务网络应用程序添加响应式行为,该应用程序最初是为 1024px 桌面屏幕设计的。

我意识到这将是一项容易出现回归的任务。 调整多个断点行为意味着我们很可能会有很多难以发现的显示错误。 我需要一种方法让我们的工程师能够在将数百个细微的布局问题提交给我们的 QA 团队之前自动发现错误。

BackstopJS 的应用场景

我想要的解决方案必须与 Web 开发人员配合使用。 也就是说,易于在本地安装,使用熟悉的 Web 开发范式,并提供合理的信心,确保为移动设备制作的选择器更改不会导致桌面布局中难以发现的错误。

当时,没有开箱即用的东西完全符合要求。 这就是创建 BackstopJS 的原因。

BackstopJS 是一个视觉回归测试应用程序,它将 CasperJSPhantomJSResembleJS 捆绑在一个易于配置的测试矩阵中,跨越多个应用程序状态(URL)、DOM 元素和屏幕尺寸。

以下是 BackstopJS 安装和初始配置的 15 分钟演练。

视觉回归测试教程

本说明将基于一个简单的演示项目(在此下载 ZIP 文件)。 它直接取自 Bootstrap 的 示例页面

扩展简单的演示

解压缩项目下载。 我们将在该示例项目中安装测试框架。

如果您在 Web 浏览器中打开myCoolProject/index.html,您将看到以下内容…请记住,它是响应式的。 因此,请确保调整浏览器窗口大小,使其变小,以查看最窄的布局!

使用 NPM 安装 BackstopJS

本教程的其余部分将需要 Node.js 环境及其集成的包管理器 (npm)。 如果您没有安装 Node 和 npm,您可以从这里获取!

现在,转到您的项目根目录(/myCoolProject/)并运行

$ cd ~/path-to-myProjects/myCoolProject
$ npm install backstopjs

您的目录现在应该如下所示

安装完成! 现在让我们进行一些基本的测试…

生成 BackstopJS 配置模板

从这里开始,基本的配置过程很简单。 为了帮助您,BackstopJS 可以生成一个配置文件,您可以根据自己的项目对其进行修改。 从myCoolProject/node_modules/backstopjs/ 目录运行

$ cd ~/path-to-myProjects/myCoolProject/node_modules/backstopjs/
$ npm run genConfig

这会将文件添加到您的项目根目录:用于 BackstopJS 屏幕截图的文件夹、backstop_data 和一个生成的基本配置文件 backstop.json

配置文件是您指定测试规则的地方。 让我们看一下该文件。

{
  "viewports": [
    {
      "name": "phone",
      "width": 320,
      "height": 480
    }, {
      "name": "tablet_v",
      "width": 568,
      "height": 1024
    }, {
      "name": "tablet_h",
      "width": 1024,
      "height": 768
    }
  ],
  "scenarios": [
    {
      "label": "My Homepage",
      "url": "https://bootstrap.ac.cn",
      "hideSelectors": [],
      "removeSelectors": [
        "#carbonads-container"
      ],
      "selectors": [
        "header",
        "main",
        "body .bs-docs-featurette:nth-of-type(1)",
        "body .bs-docs-featurette:nth-of-type(2)",
        "footer",
        "body"
      ],
      "readyEvent": null,
      "delay": 500,
      "onReadyScript": null,
      "onBeforeScript": null
    }
  ],
  "paths": {
    "bitmaps_reference": "../../backstop_data/bitmaps_reference",
    "bitmaps_test": "../../backstop_data/bitmaps_test",
    "compare_data": "../../backstop_data/bitmaps_test/compare.json",
    "casper_scripts": "../../backstop_data/casper_scripts"
  },
  "engine": "phantomjs",
  "report": ["browser", "CLI"],
  "cliExitOnFail": false,
  "debug": false,
  "port": 3001
}

在此配置中,您可以看到三个viewports 对象。 一个用于手机平板电脑纵向平板电脑横向,每个对象都有名称和尺寸属性。 您可以根据需要添加任意数量的viewports 对象。 BackstopJS 至少需要一个。

然后我们有scenarios,其中包含 BackstopJS 将测试的 URL 和元素选择器。 将每个场景对象视为特定静态页面或全局应用程序状态的测试非常有用。 根据需要添加任意数量的scenarios。 BackstopJS 至少需要一个。

每个场景内都有一个选择器列表。 选择器接受标准 CSS 表示法。 对于您指定的每个选择器,BackstopJS 将获取屏幕截图并测试您的布局的该区域。 您的选择器区域可以小到一个button,也可以大到您页面的body——查看文档以详细了解如何在动态 Web 应用程序中使用此功能

您可能会注意到,在我们刚刚生成的配置中,我们的 URL 指向 https://bootstrap.ac.cn。 如果我们现在运行 BackstopJS,我们将测试的就是它。 这是为了说明 BackstopJS 可以指向本地远程 URL,因此很容易想象将相同的测试重新用于本地开发、QA、登台和生产环境。

修改配置模板

对于我们的演示,请进行以下更改,并替换myCoolProject/backstop.json 中的scenarios 节点。

"scenarios": [
  {
    "label": "My Local Test",
    "url": "../../index.html",
    "hideSelectors": [],
    "removeSelectors": [
    ],
    "selectors": [
      "nav",
      ".jumbotron",
      "body .col-md-4:nth-of-type(1)",
      "body .col-md-4:nth-of-type(2)",
      "body .col-md-4:nth-of-type(3)",
      "footer"
    ],
    "readyEvent": null,
    "delay": 0,
    "onReadyScript": null,
    "onBeforeScript": null
  }
],

生成参考屏幕截图

myCoolProject/node_modules/backstopjs/ 目录运行…

$ npm run reference

此任务将在/myCoolProject/backstop_data/bitmaps_reference/ 中创建一个(或更新现有的)代表所有指定选择器在每个断点处的屏幕截图。 进程完成后,查看/myCoolProject/backstop_data/bitmaps_reference/ 中的内容。

到目前为止一切顺利。 我们已经设置了参考集。 现在让我们运行一个测试!

运行我们的第一个测试

我们即将运行第一个测试。但请记住,我们还没有更改 CSS 中的任何内容,因此我们的测试应该通过!

myCoolProject/node_modules/backstopjs/ 目录运行

$ npm run test

此任务将在/myCoolProject/backstop_data/bitmaps_test/<timestamp> 中创建一个新的带时间戳的测试图像目录。

生成测试图像后,BackstopJS 将打开您的 Web 浏览器并显示一个报告,将最新的测试位图与当前参考图像进行比较。 将检测并显示重要差异(如果有)。

在这种情况下,由于我们没有对测试页面进行任何更改,因此 BackstopJS 应该显示所有测试都已通过。 现在,让我们尝试更改 CSS 并看看会发生什么。

更新索引文件并运行第二个测试

如果您在 Web 浏览器中打开(未更改的)`myCoolProject/index.html`,您将看到以下内容。请注意文本周围的边距

让我们把它搞砸!打开`myCoolProject/index.html`,并在结束的`</head>`标签之前插入以下代码

<style>
  .jumbotron {
    padding: 0px;
  }
</style>

以下是页面现在的外观

这正是 Web 开发过程中经常发生的事情。一些未作用域的代码会进入并破坏您的布局,以至于您可能不会注意到 :-(

现在,从`myCoolProject/node_modules/backstopjs/`目录运行

$ npm run test

我们的测试应该再次运行,并且应该找到错误。向下滚动报告以查看我们刚刚创建的问题的视觉差异……

我们的视觉差异包含参考捕获、最新测试捕获和视觉差异文件。

找到了回归!

这是一个非常简单的例子。在现实生活中,设计师和工程师可能会发现自己正在处理非常庞大或复杂的 CSS 项目。在这种情况下,这种系统会真正提高我们工作质量和一致性。通过自动化重复的视觉任务,我们可以自信地追求更有创意的任务。

关于工作流程

有很多方法可以将这种测试集成到您的工作流程中。您可以在每次构建时触发测试,或者您也可以手动运行测试(在您工作时或在推送到下一阶段之前)。如果您愿意,您甚至可以将 BackstopJS 集成到您的 CI 管道中。所有这些主题都超出了本文的范围。查看文档以了解更多信息。

下一步

自从 2014 年首次发布以来,BackstopJS 已发展壮大。社区开发了许多新功能

  • SPA 测试支持 – 使用 Casper 脚本和显式 Web 应用程序触发器来确保在 Web 应用程序的正确时间捕获屏幕截图(例如,在 API 响应后、在 CSS 动画完成之后或等待任何其他可观察的异步进程)。
  • 模拟用户交互 – 在您的场景中使用 Casper 脚本模拟与屏幕上组件的交互。
  • CI 管道集成 – BackstopJS CLI 功能使高级用户能够将视觉回归测试作为其持续集成过程的一部分。
  • 活动配置文件 – 允许在您的配置文件中使用活动(节点模块)逻辑,您可以使用它根据环境或其他条件更改测试行为,指向不同的配置文件以将您的 BackstopJS 实例用作多个环境、垂直领域、配置文件、项目或任何其他事物的集中测试服务器。

更多关于 BackstopJS 的信息

  • BackstopJS.org
  • 查找文档、提交错误、获取故障排除帮助、了解高级功能并在 GitHub 上贡献!