在使用scss和less開發的時候,遇到過一件很有趣的事,因為網站需要支持響應式,就開了一個響應式樣式框架,簡單的幾百行scss代碼,居然生成了近100KB的css代碼,因此決定重構這個樣式庫。而重構后的項目總是出現各種各樣的問題,尤其在響應式方面,可能在一種分比率下頁面顯示正常,而在另一種分辨率下頁面卻變得面目全非,幾次調整都有遺漏的地方,忙得測試人員(其實就是我自己了)不可開交。最后總結為樣式開發也是需要做自動化回歸測試的,尤其是開發具有響應式功能的復雜樣式庫的時候,自動化測試尤其重要。
如何做前端樣式的自動化回歸測試呢?
BackstopJS就是一個能夠實現css自動化回歸測試的工具,和Mocha這種依靠JavaScript判斷斷言語句正誤和PhantomJS以模擬用戶操作的測試工具不同,BackstopJS是一個基於比較網站快照的變化的回歸測試工具,因此他更適給項目中的樣式做回歸測試,可以確保我們在重構網站樣式的時候樣式不發生變化,而且他支持設置多種瀏覽器尺寸,可以測試響應式布局。
BackstopJS具有以下特性:
- 支持多頁面、多測試用例測試
- 可以使用腳本模擬出用戶的交互動作
- 提供命令行和瀏覽器兩種形式報告
- 支持PhantomJS或SlimerJS做瀏覽器引擎,事實上兩種引擎也可以改造出基於快照對比的回歸測試方案,但是BackstopJS使用更簡單,並且做到了可以通過配置切換引擎。
- 支持設置多種瀏覽器尺寸,方便實現響應式布局測試
- 可以測試HTML5元素,比如網頁字體和Flexbox
- 提供了擴展接口,可供用戶集成到其他測試系統中
安裝方法為:
npm install -g backstopjs
使用方法:
BackstopJS的具體工作流程可以分為3步:
1.配置:該步驟用戶需要創建一個backstop.json文件,設置屏幕的尺寸、訪問頁面的url、測試區域的dom選擇器、准備事件、用戶交互等
2.准備測試樣板:生成一系列頁面快照,之后BackstopJS將根據這些快照作為頁面是否存在bug的判斷樣板
3.測試:使用當前頁面樣式快照和之前的樣板快照進行比較,如果出現不希望的變化就報告出來
BackstopJS提供了兩種使用方式,cli和commonjs模塊。cli可以提供命令行式的工具,而commonjs模塊可以讓我們在nodejs里面調用,方便繼承其他測試系統中。
我們簡單配置一個回歸測試的dome:
1.配置
這是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配置的目錄中。
2.准備樣板圖
執行命令行:
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(); }); });
在我們重構項目之前,可以運行這個腳本,這樣就可以生成樣板圖,為重構后做測試使用。
生成的樣板圖格式如下圖:

3.測試
在重構樣式后執行命令行:
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可以查看https://github.com/laden666666/BackstopJSDemo。
這里展示了backstopjs做自動化回歸測試的一個例子,backstopjs基本能夠滿足我們的需求,可以支持響應式布局測試、可以和服務器集成、可以切換瀏覽器引擎等。不過也有缺點,因為PhantomJS和SlimerJS分別是使用webkit(blink,chrome的內核)和 Gecko (Firefox內核)作為內核,因此無法模擬ie瀏覽器做測試,下一步准備繼續研究測試ie的方法。
