[自動化測試] 如何用 Protractor 寫 RWD 的畫面比對測試
之前負責一個案子,是做客戶的官方網站,且該網站有要求 RWD,而在專案後期的時候,常常一個 CSS 沒調整好,導致其他頁面跑版,於是乎我就順手寫了跑全部頁面的 E2E 跑版測試,且可以輕易擴充要測試的解析度。 今天就來說明如何建立一個這樣的 E2E 測試專案。
專案使用的套件說明
除了使用 Protractor 以外,還有使用兩個補助套件
- blue-harvest: 此套件用於圖片比較的測試。
- protractor-screenshot-utils: 使用
browser.takeScreenshot()
只會截到畫面有顯示的部分,並不會截未顯示的部分,所以要使用protractor-screenshot-utils
這個套件幫助我們整頁截圖。
專案範例說明
我這邊會以 Protractor 官方網站的Protractor Setup menu 來當作測試案例。
而完成這個專案最主要有三個步驟
這篇文章的範例專案放在 RWD-Test-Sample-by-Protractor,讀者可以邊參考專案邊看文章。
建立基底 protractor.conf.js
- js
1 | const { SpecReporter } = require('jasmine-spec-reporter'); |
上敘述的 protractor.conf.js
有五個重點:
第一個重點是 UPDATE_GOLDENS
的環境變數,用來設定是否更新 golden 圖, 1 或 true 是更新 golden 圖,反之是比對 golden 圖。
1 | process.env['UPDATE_GOLDENS'] = "true"; |
第二個重點是用來設定解析度跟儲存 golden 圖路徑的參數1
2
3
4
5
6params: {
width: 1440,
height: 568,
imagePath: 'goldens/chrome',
device: 'desktop_1440'
}
第三個重點是,SELENIUM_PROMISE_MANAGER
一定要設定為 false ,否則無法使用 blue-harvest 。
第四個重點在 capabilities
可以設定 shardTestFiles 和 maxInstances ,這可以讓 Protractor 平行跑測試,效率上會比較好。1
2
3
4
5
6SELENIUM_PROMISE_MANAGER: false,
capabilities: {
'browserName': 'chrome',
shardTestFiles: true,
maxInstances: 2,
},
第五個重點是,在 onPrepare
的時候,讀取重點二設定的解析度的參數,整條畫面的大小。1
await browser.manage().window().setSize(browser.params.width, browser.params.height);
建立測試案例
我建立了一個 Protractor-Setup.e2e-spec.ts
的測試案例,用來巡覽 Protractor Setup 底下的所有 menu。
- ts
1 | import { browser } from 'protractor'; |
這段程式碼三個重點:
第一個重點,我建立一個 array ,用來儲存要瀏覽的頁面路徑,所以以後只要有新增頁面,我在這邊新增選項就好了。1
2
3
4
5
6const urls = [
'protractor-setup',
'server-setup',
'browser-setup',
'frameworks'
]
第二個重點,使用 protractor-screenshot-utils 做整頁的截圖。1
2
3
4
5const screenShotUtils = new ProtractorScreenShotUtils({
browserInstance : browser
});
const actual = await screenShotUtils.takeScreenshot();
第三個重點,用 for 迴圈巡覽全部頁面,並且讀取剛剛在 protractor.conf.js
設定的 golden 路徑。1
2
3
4
5
6
7
8
9
10for (let index = 0; index < urls.length; index++) {
const url = urls[index];
await go(browser.baseUrl + url);
const fileName = url;
const golden = './src/' + browser.params.imagePath + `/${browser.params.device}/${fileName}.png`;
const diffDir = './src/' + browser.params.imagePath + `/${browser.params.device}/`;
const actual = await screenShotUtils.takeScreenshot();
const result = await compareScreenshot(actual, golden, diffDir);
expect(result).toBeTruthy();
}
執行 E2E 測試
上敘步驟完成後,我們可以將測試執行起來 npm run protractor
,執行後就會看到 golden 圖儲存到設定的路徑上。
這樣未來只要把 UPDATE_GOLDENS
的環境變數清空或者設定成 false ,就可以跟 golden 做比對了1
2//in protractor.conf.js
process.env['UPDATE_GOLDENS'] = "false";
新增其他解析度的 protractor.conf.js
因為畫面的大小是寫在 browser.params
, 所以只要新增 protractor.conf.js
覆寫掉 browser.params
就可以快速產生不同解析度的測試,而且程式碼都不需要調整。 我這邊以新增一個 pad 解析度為例 protractor.conf.pad_768.js
1
2
3
4
5
6
7
8
9
10let config = require('./protractor.conf.js').config;
config.params = {
width: 768,
height: 1024,
imagePath: 'goldens/chrome',
device: 'pad_768'
};
exports.config = config;
然後在 package.json 新增 protractor.conf.pad_768.js
的 E2E 測試指令1
2
3
4"scripts": {
"protractor": "protractor",
"chrome:768": "protractor protractor.conf.pad_768.js",
},
執行 npm run chrome:768
後就會看到 golden 圖儲存到設定的路徑上。
小結
透過這樣的方式,就可以寫少少的程式碼,快速把網站所有的頁面跑過一次跑版測試,並且保有擴充性,可以隨意新增要測試的解析度,甚至是不同的瀏覽器,只要新增 protractor.conf.js
並覆寫設定就可以了。
另外,如果需要有更新 golden 圖的時候,只要使用 configuring-test-suites 或者是 fdescribe 來部分更新 golden 圖就可以了。