在使用 sCSS 和 less 开发的时候,遇到过一件很有趣的事,因为网站需要支持响应式,就开了一个响应式样式框架,简单的几百行 scss 代码,居然生成了近 100KB 的 css 代码,因此决定重构这个样式库。而重构后的项目总是出现各种各样的问题,尤其在响应式方面,可能在一种分比率下页面显示正常,而在另一种分辨率下页面却变得面目全非,几次调整都有遗漏的地方,忙得测试人员(其实就是我自己了)不可开交。最后总结为样式开发也是需要做自动化回归测试的,尤其是开发具有响应式功能的复杂样式库的时候,自动化测试尤其重要。
如何做前端样式的自动化回归测试呢?
BackstopJS 就是一个能够实现 css 自动化回归测试的工具,和 Mocha 这种依靠 JavaScript 判断断言语句正误和 PhantomJS 以模拟用户操作的测试工具不同,BackstopJS 是一个基于比较网站快照的变化的回归测试工具,因此他更适给项目中的样式做回归测试,可以确保我们在重构网站样式的时候样式不发生变化,而且他支持设置多种浏览器尺寸,可以测试响应式布局。
- npm install -g backstopjs
BackstopJS 的具体工作流程可以分为 3 步:
1. 配置:该步骤用户需要创建一个 backstop.json 文件,设置屏幕的尺寸、访问页面的 url、测试区域的 dom 选择器、准备事件、用户交互等
2. 准备测试样板:生成一系列页面快照,之后 BackstopJS 将根据这些快照作为页面是否存在 bug 的判断样板
3. 测试:使用当前页面样式快照和之前的样板快照进行比较,如果出现不希望的变化就报告出来
BackstopJS 提供了两种使用方式,cli 和 commonjs 模块。cli 可以提供命令行式的工具,而 commonjs 模块可以让我们在 nodejs 里面调用,方便继承其他测试系统中。
这是 BackstopJS 的核心,配置文件默认名为 backstop.json,下面是测试配置的示例:
- {
- //测试用例id,用于BackstopJS管理和为文件命名
- "id": "backstop_prod_test",
- //测试视口,就是配置各种分辨率
- "viewports": [
- {
- "name": "phone",
- "width": 320,
- "height": 480
- }],
- //在执行所有脚本前、页面加载后执行的脚本。通过他我们可以执行用express做一个静态服务器
- "onBeforeScript": "onBefore.js",
- "onReadyScript": "onReady.js",
- //测试用例
- "scenarios": [
- {
- //测试用例名称
- "label": "homepage",
- //测试的地址
- "url": "https://garris.github.io/BackstopJS/",
- //测试的区域,支持css选择器,然后BackstopJS会将选择器指定的地方截屏
- "selectors": [
- ".class",
- "#id"
- ],
- "selectorExpansion": true,
- "hideSelectors": [],
- "removeSelectors": [],
- "readyEvent": null,
- "delay": 500,
- "misMatchThreshold" : 0.1,
- //在各种的测试用例执行时、页面加载后前行,我们可以把我们对页面操作的模拟脚本放进onReady.js中
- "onBeforeScript": "onBefore.js",
- "onReadyScript": "onReady.js"
- }
- ],
- //测试图片的输出路径
- "paths": {
- "bitmaps_reference": "backstop_data/bitmaps_reference",
- "bitmaps_test": "backstop_data/bitmaps_test",
- "casper_scripts": "backstop_data/casper_scripts",
- "html_report": "backstop_data/html_report",
- "ci_report": "backstop_data/ci_report"
- },
- //测试用的浏览器或模拟器,这里用的是PhantomJS
- "engine": "phantomjs",
- //报告的形式,支持命令行和浏览器两种
- "report": ["browser"],
- //是否打印测试日志
- "debug": false
- }
通过设置 viewports 我们可以配置多种屏幕尺寸,这样可以完成响应式布局的测试。
scenarios 可以配置多个测试用例。url 指定了需要测试页面的地址;selector 指定要测试的区域,如果整个页面都是测试区域可以直接给 document 或者是 body。
在测试用例的 onReadyScript 中我们可以设置模拟用户的操作的脚本,如:
- module.exports = function(casper, scenario, vp) {
- // Example: setting cookies
- casper.echo("Setting cookies");
- casper.then(function() {
- casper.page.addCookie({
- some: 'cookie'
- });
- });
- // `casper.thenOpen()` demonstrates a redirect to the original page with your new cookie value.
- // this step is not required if used with _onBeforeScript_
- casper.thenOpen(scenario.url);
- // Example: Adding script delays to allow for things like CSS transitions to complete.
- casper.echo('Clicking button');
- casper.click('.toggle');
- casper.wait(250);
- // Example: changing behavior based on config values
- if (vp.name === 'phone') {
- casper.echo('doing stuff for just phone viewport here');
- }
- // ...do other cool stuff here, see Casperjs.org for a full API and many ideas.
- }
这些脚本都是放在 casper_scripts 配置的目录中。
执行命令行:
- backstop reference
backstop 会自动截取屏幕整个样板图,并会存在 bitmaps_reference 指定的路径下。
为了能够和服务器集成,我们使用 commonjs 模块的形式调用 backstopjs,如:
- var http = require('http');
- var express = require('express');
- var backstop = require('backstopjs');
- var path = require('path');
- var app = express();
- app.use("/", express.static(path.join(__dirname ,'../html/')));
- // 创建服务端
- var sever = http.createServer(app).listen('3000', function() {
- //执行backstop
- backstop('reference').then(function () {
- sever.close();
- });
- });
在我们重构项目之前,可以运行这个脚本,这样就可以生成样板图,为重构后做测试使用。
生成的样板图格式如下图:
在重构样式后执行命令行:
- backstop test
同样为了能够和服务器集成,我们使用 commonjs 模块的形式调用 backstopjs,如:
- var http = require('http');
- var express = require('express');
- var backstop = require('backstopjs');
- var path = require('path');
- var app = express();
- app.use("/", express.static(path.join(__dirname ,'../html/')));
- // 创建服务端
- var sever = http.createServer(app).listen('3000', function() {
- //执行backstop
- backstop('test').then(function () {
- sever.close();
- });
- });
如果新生成的图片和样板图不一样,就会报错。生成的报告有两种形式——命令行报告和浏览器报告,这里展示的是浏览器报告结果:
详细 demo 可以查看。
这里展示了 backstopjs 做自动化回归测试的一个例子,backstopjs 基本能够满足我们的需求,可以支持响应式布局测试、可以和服务器集成、可以切换浏览器引擎等。不过也有缺点,因为 PhantomJS 和 SlimerJS 分别是使用 webkit(blink,chrome 的内核) 和 Gecko (Firefox 内核) 作为内核,因此无法模拟 ie 浏览器做测试,下一步准备继续研究测试 ie 的方法。
来源: