用Node.js撰寫CSS測試


目前主流CSS的測試方法都是「截圖比對」,這跟一般寫測試的邏輯不太一樣。

因為撰寫CSS測試是一件拐彎抹角的事情,主要是測試大多以「是否完成某個目的」為判斷基準。但對於CSS測試來說,CSS完全是排版的東西,很難有一個目的來判斷,例如我們可以測試1+1是否等於2但卻很難測試這個div是否距離左邊3px,一來會有優先權的問題導致某些設定好的數值無法發揮效果,二來又會有z-index等不同的因素導致DOM互相遮蔽。

因此,目前最主流的測法就是用截圖,直接用最後的執行結果畫面當做比對基準,先截一張圖當做標準,再用第二張圖來比對。

BackstopJS demo

這邊簡單用BackstopJS當做範例,示範要如何進行CSS測試。由於要測試CSS一定都跟前端有關,所以目前有在檯面上的CSS測試framework幾乎都是用javascript所寫。CSS-Tricks上有非常詳盡的說明,但有點過於囉嗦,我這邊稍微整理一下。

安裝

這部份最囉嗦,因為本人對NodeJS並沒有很熟,導致踩到很多地雷。首先要確定所有相關套件都有裝上。

NodeJS

$ brew install node
$ node --version (確認有安裝成功)

Bower

$ npm install -g bower
$ bower --version

PhantomJS

$ npm install -g phantomjs
$ phantomjs --version

CasperJS

$ npm install -g casperjs
$ casperjs --version

Gulp

$ npm install -g gulp
$ gulp --version

如果你的brew不是安裝在root底下,所有npm要安裝的內容都會需要加上sudo,這比較是個人習慣問題,沒有強迫的方式。

這邊要提醒一下,如果沒有加上-g,就會在你當前的資料夾底下新增node_modules資料夾,並把套件裝在裡面,這會造成之後的安裝有問題。因為npm管理套件是以資料夾為單位,如果你的上層已經有node_modules資料夾,他會把目前的資料夾當做子資料夾,而去抓上層的node_modules資料夾。請務必確認node_modules資料夾只會存在於你的專案資料夾內,就像你不會把自己的系統根目錄放一個.git資料夾一樣。

產生專案設定檔

要到你的一個專案資料夾內(開一個新的空專案也可),在專案的根目錄底下執行(請注意執行的資料夾位置,這會影響到後續的步驟):

$ bower install backstopjs
$ cd bower_components/backstopjs
$ npm install
$ gulp genConfig

順利的話會出現一個backstop.json的檔案,但他並不會出現在目前的資料夾內,而是出現在專案資料夾的根目錄內,所以請執行:

$ cd ../..
$ ls

順利的話就會看到backstop.json檔案。

設定

設定檔分為兩塊,首先看到viewports的部份:

"viewports": [
  {
    "name": "phone",
    "width": 320,
    "height": 480
  },
  {
    "name": "tablet_v",
    "width": 568,
    "height": 1024
  },
  {
    "name": "tablet_h",
    "width": 1024,
    "height": 768
  }
]

這部份代表你要測試的裝置列表,這三個裝置都是手機和平板,你可以自行加上桌機的寬高,記得不要把json格式打亂,要將所有裝置都塞在viewports數列內。

"scenarios": [
  {
    "label": "https://getbootstrap.com",
    "url": "https://getbootstrap.com",
    ,"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": 500
  }
]

這邊有幾個可以修改的部份,但最主要會用到的有幾個:

  1. label:你的測試要叫什麼名字
  2. url:抓取的位址
  3. hideSelectors:主要用於測試動態內容,因為許多網頁DOM會從資料庫抓檔案,動態內容的截圖必定會比對錯誤,所以我們可以隱藏動態內容顯示的地方。例如顯示隨機文章的欄位,我們要將文章內容隱藏,只擷取文章的外框,則可以填入css selector "div.container .post-content",而在下面selector的欄位,填入"div.container",這樣他就只會抓取container class的div,而會忽略裡面post-content class的div。
  4. removeSelectors:如果網頁內的DOM會有無法預期的大小,例如隨機寬高,那這裡可以填入該元素,他便會設定該元素為"display: none"直接省略。同樣使用css selector寫。
  5. selectors:使用的css selector名稱,可以用一般的.代表class、#代表id
.6 delay:進入網頁以後需要等待多久再開始抓取,一般預設的500其實已經足夠,除非網頁肥大或有許多ajax request需等待完成,這時才需要較久的時間。

預設的設定檔可以看到他會去https://getbootstrap.com抓取資料,假如我們依照自己的需求修改完成,這時在專案根目錄底下的/bower_components/backstopjs執行:

$ gulp reference
記得,如果執行的目錄位置不對,他會請你npm install,如果你已經裝過了,請確認執行的位置是否正確即可。如果不小心再npm install一次,會產生其他的node_modules資料夾,這些都會產生混淆和錯誤。

假如沒發生錯誤的話,這個指令會把要比對的資料先擷取圖片,存檔,當做判斷基準。這時再執行:

$ gulp test

這時他會用https://localhot:3001開啟一個網頁,裡面就是我們的測試內容,他會逐一比對跟reference所抓的圖片是否有任何不同。

其他

CSS測試跟一般軟體測試最大的不同在於他沒有TDD,一定要先把網頁內容寫好,才能用截圖的方式產生reference。也就是說CSS測試最主要的功能是修改網站設計時,預防你改一個class設計卻因為剛好有其他DOM採用相同的class而爆掉。

CSS 參考資料

CSS Selector寫法

CSS Cheat Sheet

CSS 撰寫測試參考資料

CSS-Tricks

BackstopJS關方說明文件

圖片來源

Pixabay