在使用scss和less開發的時候,遇到過一件頗有趣的事,由於網站須要支持響應式,就開了一個響應式樣式框架,簡單的幾百行scss代碼,竟然生成了近100KB的css代碼,所以決定重構這個樣式庫。而重構後的項目老是出現各類各樣的問題,尤爲在響應式方面,可能在一種分比率下頁面顯示正常,而在另外一種分辨率下頁面卻變得面目全非,幾回調整都有遺漏的地方,忙得測試人員(其實就是我本身了)不可開交。最後總結爲樣式開發也是須要作自動化迴歸測試的,尤爲是開發具備響應式功能的複雜樣式庫的時候,自動化測試尤爲重要。css
如何作前端樣式的自動化迴歸測試呢?html
BackstopJS就是一個可以實現css自動化迴歸測試的工具,和Mocha這種依靠JavaScript判斷斷言語句正誤和PhantomJS以模擬用戶操做的測試工具不一樣,BackstopJS是一個基於比較網站快照的變化的迴歸測試工具,所以他更適給項目中的樣式作迴歸測試,能夠確保咱們在重構網站樣式的時候樣式不發生變化,並且他支持設置多種瀏覽器尺寸,能夠測試響應式佈局。前端
npm install -g backstopjs
BackstopJS的具體工做流程能夠分爲3步:node
1.配置:該步驟用戶須要建立一個backstop.json文件,設置屏幕的尺寸、訪問頁面的url、測試區域的dom選擇器、準備事件、用戶交互等ios
2.準備測試樣板:生成一系列頁面快照,以後BackstopJS將根據這些快照做爲頁面是否存在bug的判斷樣板git
3.測試:使用當前頁面樣式快照和以前的樣板快照進行比較,若是出現不但願的變化就報告出來github
BackstopJS提供了兩種使用方式,cli和commonjs模塊。cli能夠提供命令行式的工具,而commonjs模塊可讓咱們在nodejs裏面調用,方便繼承其餘測試系統中。web
這是BackstopJS的核心,配置文件默認名爲backstop.json,下面是測試配置的示例:chrome
{ //測試用例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咱們能夠配置多種屏幕尺寸,這樣能夠完成響應式佈局的測試。express
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能夠查看https://github.com/laden666666/BackstopJSDemo。
這裏展現了backstopjs作自動化迴歸測試的一個例子,backstopjs基本可以知足咱們的需求,能夠支持響應式佈局測試、能夠和服務器集成、能夠切換瀏覽器引擎等。不過也有缺點,由於PhantomJS和SlimerJS分別是使用webkit(blink,chrome的內核)和 Gecko (Firefox內核)做爲內核,所以沒法模擬ie瀏覽器作測試,下一步準備繼續研究測試ie的方法。