Protractor 是一款 end-to-end test framework. 什麼是 end-to-end test 呢?! 簡單的說它可以模擬 user 在 browser 上操作的所有行為(近乎 100%), 進而測試頁面 flow 是否順暢? JavaScript 各 module 是否運作正常? 如果寫得好的話, 取代傳統的人工測試使之進化到全自動化測試也不再是件遙不可及的夢想。
Protractor 可以搭配的 behavior driven development(BDD) framework 分別有 Jasmine(default)、Mocha 以及 Cucumber, 我這裡所撰寫的 testing code 是 base 在 Cucumber 上, 因此以下將介紹如何設定 Protractor 以及 Chumber.
首先先來看一下使用 protractor 來作 testing 的步驟, 筆者本身的 OS 為 windows 7, 所以以下截圖均是 win 7 為基底.
※ 啟動 webdriver-manager
要開始測試之前, 我們必須要先把 Selenium Server 給 on 起來, 請先開啟 Node.js command prompt
並在該視窗輸入 webdriver-manager start, 即可將之啟動
啟動完成後, 其 default 的 server status page 為 http://localhost:4444/wd/hub, 直接在 browser 鍵入該網址, 應該要可以看到相關的 infomation.
※ 進到存放 test code 的 folder
請先開啟另一個 Node.js command prompt , 並前往欲進行 testing 的 folder
如同上圖, 筆者有對 google search 寫些簡單的範例, 所以便直接前往該 folder
※ 開始使用 protractor 來進行 testing
直接鍵入下列指令, 並可以開始進行測試
protractor google.conf.js
testing 完成後, 我們即可在該視窗觀看到方才的測試結果, 我們可以看到有兩個 scenarios 成功 pass 了, protractor config 被執行後, 便會依照其內容所設定的幫我們把 「Cucumber」 和 「 Selenium Server」建立起良好的溝通橋樑, 並讓 testing 順利的進行.
以上便是透過 protractor 來進行 testing 的基本流程, 其中最為關鍵的莫過於該 config file – google.conf.js, 這也是本篇主要想要闡述的主題, 究竟要如何對 config 進行設置, 才能讓 protractor 照我們想走的流程下去走呢?! 接下來就讓我們來觀看該 config 究竟施展了哪些承先啟後的魔法吧!
基本上, 我們想到的, protractor 大致上都已經做好了, 只要透過簡單的設定, 便可以了, 接下來會針對 config 的基本屬性來進行介紹
※ Config Attributes:
- seleniumAddress: 透過該屬性的設置可以決定我們要啟的 browser 位址, 它可以是打 local 或者是進行 remote.
seleniumAddress: ‘http://localhost:4444/wd/hub’
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L9
- specs: 設定欲進行 testing 的 feature 檔路徑, 它可以是 array 或者是單一字串
specs: ‘cucumber/**/*.feature’
or
specs: [‘cucumber/google/a.feature’, ‘cucumber/google/b.feature’]
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L15
- suites: 透過該屬性的設置, 我們可以把不同的 feature 進行 group 的動作, 並且可以針對不同的 suite 進行 testing, 來增加 testing 的靈活度
suites : {
navigation: ‘cucumber/navigation/*.feature’,
dragon: ‘cucumber/dragon/**/*.feature’,
google: ‘cucumber/google/**/*.feature’,
boothSRP: [
‘cucumber/booth/boothSRP.feature’,
‘cucumber/layout/**/*.feature’
]
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L18
如同上面的例子, suite 這個 object 是以 key / value pair 來作兩兩相對, value 除了是 string 外, 一樣可以是 array, 要針對特定 suite 進行測試的時候只要加上 –suite [suiteKey], 如下所示
protractor google.conf.js –suite google
- capabilities: 設定欲進行測試的 browser 相關屬性, Protractor supports the two latest major versions of Chrome, Firefox, Safari, and IE
capabilities: {
browserName: ‘chrome’
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L27
如果要設定 ie 的話, 則需要額外安裝該 webdriver. 可以透過下列的指令進行安裝
webdriver-manager update –ie
另外這個屬性還可以發揮其它的功用喔! 如果想要 run test in parallel, 也是需要透過這個屬性來作喔!
capabilities: {
browserName: ‘chrome’,
shardTestFiles: true,
maxInstances: 3
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L116
透過上面的設定, protractor 會起三個 browser 來進行 test, 基本上它是以「單一 feature 」為單位, run 完之後會自動關閉該 browser 並繼續尋找下一個 feature 來作測試, 若 feature 已驗完則結束, 反之, 則不斷重複這樣的 loop, 直到結束為止
不過要 run test in parallel 之前, 必須要注意各 feature 是否可以獨立運作, 如果 feature 間會互改同一物件設定的話, 則 scenario 可以就會亮出很多紅燈(fail)喔!
- multiCapabilities : 該屬性的設置其實就是 capabilities 的延伸, 透過設定則可以同時起不同的 browser 來進行設置
multiCapabilities: [
{
browserName: ‘firefox’
},
{
browserName: ‘chrome’
}
]
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L30
接下來要介紹的是屬於 method 類型, 每一個 method 均會再 test 開始 run 之前或者之後被觸發, 方便我們作一些「前置作業」或者是「清理現場」的動作喔!
- beforeLaunch: 如同其名, 它會再 test 開始 run 之前被觸發, 特別注意, global 變數在此均尚未被 init 起來, 也就是說 protractor / browser 均為 undefined. 通常我們會在這個 method 作些前置作業, 筆方說 清除 || 搬移 上回測試的結果, 或者是把接下欲進行的商品先 on 起來, 讓接下來的測試可以順暢進行
beforeLaunch: function() {
//do some clear action
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L36
- onPrepare: 一樣是在 run test 之前會被觸發, 不同於 beforeLauch, 在這裡已經可以使用 global 變數了, 另外也可以在這裡將可能會用的 js require 進來, 亦或是設置些 global 變數
onPrepare: function() {
var chai, chaiAsPromised;
browser.ignoreSynchronization = true;
chai = require(‘chai’);
chaiAsPromised = require(‘chai-as-promised’);
chai.use(chaiAsPromised);
global.__base = __dirname;
global.expect = chai.expect;
global.common = require(__base + ‘/lib/common.js’);
global.constants = require(__base + ‘/lib/constants.js’);
global.PageObject = require(__base + ‘/lib/pages/pageObject.js’);
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L60
如上所示, 由於筆者使用 chai as assertion, 為了避免不同的 step definition 作些重複的動作, 因此在該 method 就直接把它 require 進來並且設置成 global 變數, 方便接下來的使用, 另外, 要特別注意的是 … 如果你的 application 非 AngularJS based 的, 則必須要設置 「ignoreSynchronization」為 true, 避免出現不預期的錯誤!!
- onComplete: 該 method 會在所有 feature 均被執行完後被觸發, 此時 global object 依舊存在喔! 如果是 run in parallel 的話, 則每執行完一個 feature 均會觸發本 method 一回喔!
onComplete: function() {
// do something after test
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L74
- onCleanUp: 該 method 僅會被觸發一回, 觸發時機則落在所有 test run 完且 Webdriver instance 被 shut down
onCleanUp: function() {
// do something after test and webdriver instance has been shut down
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L76
- afterLaunch: 該 method 會在 onCleanUp 後被觸發, 此刻已經沒有任何的 global object 可以被 access 了, 且如同 onCleanUp 一樣, 它僅會被 trigger 一回
afterLaunch: function() {
// do something
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L78
- params: 這是 protractor 所提供的 global object, 我們可以對它作 set / get 的動作, 方便跨 scenario 變數傳遞, 當然也可以存放些有用的資訊, 比方說 user 登入的 cookie, 在作不同 account login 的時候, 便可以直接 plug 相關的 infomation.
param: {
loginId: ”,
forceRefresh: ”
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L80
- resultJsonOutputFile: 這是 protractor 所提供的新功能, 透過該屬性的設置, 就可以把每次 run 完的 test 結果以 JSON format 被存放出來喔! 如下所示, 結果將會存放到 result 這個 folder 裡面, 檔案名稱為 result.json
resultJsonOutputFile: ‘result/result.json’
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L84
最後, 終於要進入到 framework setting 的 section 了, 這裡僅會作 Cucumber 的相關設定介紹
- framework: 設定欲使用的 BDD fremework
framework: ‘cucumber’
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L90
- cucumberOpts: 設置 Cucumber 的細部設定
cucumberOpts: {
require: ‘cucumber/**/*.js’,
tags: [
process.env.tags || ‘@E2E,@SMOKE,@REGRESSION,@FUNCTIONALITY’,
‘~@X’
],
format: ‘summary’
}
git: https://github.com/meistudioli/protractorEx/blob/master/google.conf.js#L91
- require 是用來設置想要 boundle 的 step definition, 它可以是 string 或者是 array 的方式進行宣告
- tags 這是 Cucumber 強大的項目之一, 我們可以在每個 scenario 上設置 tag 來方便我們針對特定 scenario 進行設置, 它可以是 string 或者是 array, 單一 element 用 , 隔開是作 or, 不同 element 則是作 and. 以上面為例它會 run 的 tag 有 (@E2E && ~@X) || (@SMOKE && ~@X) || (@REGRESSION && ~@X) || (@FUNCTIONALITY && ~@X)
- format run 完 test 後所呈現的格式, 可以是 summary || json || pretty
以上, 便是我個人比較常用且會設置的屬性, 當然其它屬性待大家來發掘其可用的時機, 可以前往 protractor 官網官看細部設定, 此外, 我們可以透過 process.env 來動態調整個屬性的 value, 讓 config file 可以更加的靈活有趣喔!
example:
capabilities: {
browserName: process.env.browserName || ‘chrome’
}
歡迎有興趣的朋友前往觀看我放在 git 上的 file, 有任何問題的話, 亦請不吝指教, 讓我們在相互討論間共同學習, 一起成長吧!!
※ Reference:
※ 延伸閱讀:
Protractor – 實戰篇 – the last puzzle piece