哪個才是最適合你的 Web UI 自動化測試框架
最近,專案上出於系統性穩定性、減少測試工作量考慮,打算在 Web 前端引入 BDD。由於上一個專案寫了一定的 Cucumber 程式碼(BDD 測試框架之一),這個框架選型的責任便落到了我的肩膀上了。
在我們進行框架選型的時候,著重考慮了一個因素:
測試實現指令碼是由開發人員編寫的,因此最好尋找 JavaScript 支援的框架
。在搜尋了一天後,選擇了三個框架 Cucumber、Robot、Gauge。以下是上述的三個框架入選的原因:
Cucumber
,團隊的開發人員有一些有相關的開發經驗、支援 JavaScript。
Robot Framework
,測試人員接受過相關的培訓、不支援 JavaScript。
Gauge
,可以生成更好的測試報告及自由的書寫、支援 JavaScript。不過,主要是我寫膩了 Cucumber。
隨後,便使用三個不同的框架寫了幾個 UI 測試的 DEMO。在開始之前,讓我們瞭解什麼是 BDD。
BDD
Behavior Driven Development,行為驅動開發是一種敏捷軟體開發的技術,它鼓勵軟體專案中的開發者、QA 和非技術人員或商業參與者之間的協作。
與一般的自動化測試(如單元測試、服務測試、UI 測試)不一樣的是,BDD 是由多方參與的測試開發方式。如在使用 Protractor 寫 Angular 的 E2E 測試的時候,所以的測試都是前端測試人員編寫的。BDD 最重要的一個特性是:由
非開發人員編寫測試用例
,而這些測試用例是使用
自然語言編寫的 DSL(領域特定語言)
。
換多話來說,業務人員、測試人員、客戶等利益相關者,以習慣的方式編寫相關的測試用例,再由開發人員去實現相關的測試。如下圖所示:
BDD 流程
由業務人員編寫的測試用例,將是使用如下的形式實現的:
* 當我在網站的首頁
* 輸入使用者名稱 “demo”
* 輸入密碼 “mode”
* 提交登入資訊
* 使用者應該跳轉到歡迎頁
對於能支援中文的 BDD 框架來說,這就是業務人員和測試人員等編寫的用例,他們能輕鬆地編寫出這樣的用例,而開發人員便是去實現這一個又一個的 DSL 語句。
在我之前的一個專案裡,我們遇到了一個問題:
測試用例也是由開發人員編寫的
。這種做法不僅不能體現 BDD 的價值,而且對於開發人員來說,這是在糟蹋程式碼。如果完全是由開發人員編寫的測試,那麼為什麼我們需要寫一個額外的 DSL 層呢?
接下來,讓我們看看三個測試的一個簡單對比表:
BDD 框架對比
從某程程度上來看,三個框架差不了多少,每個框架也各自都有自己的問題。
Cucumber 的 Javascript 版本不支援 HTML 的報表生成。
Gauge 雖然比較適合我們的要求,但是相關的中文資料比較少。
Robot 主要的問題是不支援 JavaScript,以及要按 Robot 定義的方式來編寫程式碼。
以下是三個框架的示例及詳細的對比。
Cucumber.js
Cucumber 是一個能夠理解用普通語言 描述的測試用例的支援行為驅動開發(BDD)的自動化測試工具,用Ruby編寫,支援Java和。Net等多種開發語言。
使用自然語言,更易讀
支援表格引數
支援多種格式的Report:html、junit etc。
支援多種語言
支援四種狀態的測試步驟:Passed、Failed、Skipped、Pending
支援使用變形器消除重複
一個商用的線上 Cucumber 系統:Cucumber Pro
DSL Code Examples
示例程式碼:
https://
github。com/phodal/bdd-f
rameworks-compare/tree/master/cucumber
#
language
:
zh
-
CN
功能
:
失敗的登入
場景大綱
:
失敗的登入
假設
當我在網站的首頁
當
輸入使用者名稱
<
使用者名稱
>
當
輸入密碼
<
密碼
>
當
提交登入資訊
那麼
頁面應該返回
“Error Page”
例子
:
|
使用者名稱
|
密碼
|
|
‘Jan1’
|
‘password’
|
|
‘Jan2’
|
‘password’
|
Cucumber 支援比較固定的 DSL 格式,即三段式 Given-When-Then,對應的中文便是:假設-當-那麼。作為一個歷史悠久的框架,它的中文資料相當的豐富,只是在 JavaScript 方面有些不足,不能生成對應的 HTML 報告。
其實現程式碼如下所示:
Step Code Examples
defineSupportCode
(
function
({
Given
,
When
,
Then
})
{
Given
(
‘當我在網站的首頁’
,
function
()
{
return
this
。
driver
。
get
(
‘http://0。0。0。0:7272/’
);
});
When
(
‘輸入使用者名稱 {string}’
,
function
(
text
)
{
return
this
。
driver
。
findElement
(
By
。
id
(
‘username_field’
))。
sendKeys
(
text
)
});
When
(
‘輸入密碼 {string}’
,
function
(
text
)
{
return
this
。
driver
。
findElement
(
By
。
id
(
‘password_field’
))。
sendKeys
(
text
)
});
When
(
‘提交登入資訊’
,
function
()
{
return
this
。
driver
。
findElement
(
By
。
id
(
‘login_button’
))。
click
()
});
Then
(
‘頁面應該返回 {string}’
,
function
(
string
)
{
this
。
driver
。
getTitle
()。
then
(
function
(
title
)
{
expect
(
title
)。
to
。
equal
(
string
);
});
});
});
從程式碼實現上來說,也是固定的三段式。其底層依賴於 Selenium,因此寫法上與 Gauge 的區別並不大。
Robot Framework
Robot Framework是一款python編寫的功能自動化測試框架。具備良好的可擴充套件性,支援關鍵字驅動,可以同時測試多種型別的客戶端或者介面,可以進行分散式測試執行。
關鍵特性:
使用關鍵字的機制,更容易上手
提供了RIDE,對於不熟悉編碼的人來說比較友好
能夠精細的控制關鍵字的scope
Log 和 Report 非常好
使用變數檔案的機制來描述不同的環境
豐富的關鍵字型檔
內建變數
DSL Code Examples
示例程式碼:
https://
github。com/phodal/bdd-f
rameworks-compare/tree/master/robot
*** Settings ***
Documentation 登入測試 2
。。。
Suite Setup 開啟瀏覽器到登入頁1
Suite Teardown Close Browser
Test Setup 轉到登入頁
Test Template 使用錯誤的失敗憑據應該登入失敗
Resource resource。robot
*** Test Cases *** USER NAME PASSWORD
無效的使用者名稱 invalid ${VALID PASSWORD}
無效的密碼 ${VALID USER} invalid
無效的使用者名稱和密碼 invalid whatever
*** Keywords ***
使用錯誤的失敗憑據應該登入失敗
[Arguments] ${username} ${password}
輸入使用者名稱 ${username}
輸入密碼 ${password}
提交登入資訊
登入應該不成功
登入應該不成功
Location Should Be ${ERROR URL}
Title Should Be Error Page
從上面的程式碼來看,Robot 在某些特定的關鍵字上,必須使用英語。在關鍵的程式碼如關閉瀏覽器,仍然需要使用 Close Browser 英語這些來實現。
Step Code Examples
開啟瀏覽器到登入頁
Open Browser ${LOGIN URL} ${BROWSER}
Maximize Browser Window
Set Selenium Speed ${DELAY}
Login Page Should Be Open
Login Page Should Be Open
Title Should Be Login Page
轉到登入頁
Go To ${LOGIN URL}
Login Page Should Be Open
輸入使用者名稱
[Arguments] ${username}
Input Text username_field ${username}
輸入密碼
[Arguments] ${password}
Input Text password_field ${password}
提交登入資訊
Click Button login_button
應該跳轉到歡迎頁
Location Should Be ${WELCOME URL}
Title Should Be Welcome Page
與上面的 Cucumber 相比,Robot 對於英語的非開發人員來說更加友好。換句話來說,Robot 更像是一個適合於 QA 的語言。作為一個開發人員,可能不太喜歡這種形式。
報告示例
不過,Robot 提供了一份說盡的報告。細緻的展示了每一個測試,以及其步驟時間等等。
Gauge
Gauge 是 Go 開發的一個跨平臺測試自動化工具。它給作者提供了用商業語言測試用例的能力。
關鍵特性:
基於 markdown 的豐富的標記
支援用任何程式語言來編寫測試程式碼
支援 plugin 的模組化架構
跨語言實現一致性。
簡單,靈活和豐富的語法
開源的,因此它可以自由共享,同時被他人改進
商業語言測試 : 支援可執行檔案的概念
幫助您建立可維護和可理解的測試套件
支援外部資料來源
IDE Support
DSL Code Examples
示例程式碼:
https://
github。com/phodal/bdd-f
rameworks-compare/tree/master/gaugejs
失敗的登入
===
|使用者名稱 |密碼 |
|————|————|
|Jan1 |password|
|Jan2 |password|
失敗的登入
——————-
* 當我在網站的首頁
* 輸入使用者名稱 <使用者名稱>
* 輸入密碼 <密碼>
* 提交登入資訊
* 頁面應該返回 “Error Page”
與 Robot 和 Cucumber 不一樣的是,Gauge 使用的是大家更熟悉的 Markdown 形式的 DSL。並且從形式上來說,更加自由。List 中的每一行,就代表著一個元素。因此,其對應的實現程式碼也更加的自由。
Step Code Examples
step
(
“當我在網站的首頁”
,
async
function
()
{
await
page
。
goto
(
‘http://0。0。0。0:7272/’
);
});
step
(
“輸入使用者名稱
,
async
function
(
query
)
{
await
page
。
click
(
‘#username_field’
);
await
page
。
type
(
query
)
});
step
(
“輸入密碼
,
async
function
(
query
)
{
await
page
。
click
(
‘#password_field’
);
await
page
。
type
(
query
)
});
step
(
“提交登入資訊”
,
async
function
()
{
await
page
。
click
(
‘#login_button’
)
});
step
(
“頁面應該返回
,
async
function
(
query
){
await
page
。
waitFor
(
‘h1’
);
const
text
=
await
await
page
。
$eval
(
‘#container h1’
,
h1
=>
{
return
h1
。
innerHTML
;
});
expect
(
text
)。
to
。
equal
(
query
);
});
上面採用的是 Node。js 8 支援的非同步寫法,除此與 cucumber。js 寫的程式碼並沒有太多的差異。
報告示例
至於,Gauge 生成的 UI 並沒有 Robot 那麼詳細,但是看上去現代。
那麼,你喜歡哪個 BDD 框架呢?
詳細程式碼見:phodal/bdd-frameworks-compare