BDD是什么
BDD,Behavior Driven Development,行為驅動開發。
如果你不是很了解BDD,可以參考我四年前的一篇文章說起BDD,你會想到什么,其中介紹過BDD的理論和應用。
我們可以這樣來概括BDD:
- BDD采用統一的領域特定語言(DSL)來描述業務場景和用戶行為,讓團隊各個不同角色對業務需求有一致認識,從而做到更有效的溝通和更高效的協作;
- BDD的目的不是自動化測試,但是BDD可以有效指導自動化測試,基于BDD的自動化測試相當于維護了一份需求活文檔,對項目需求的維護和管理非常有價值。
BDD應用框架之Cucumber
BDD的應用
BDD是為解決下面三個方面的問題而生:
- 協作:多個角色在一個團隊,如何從一致理解需求開始高效協作?
- 語言:不同的角色業務、開發和測試人員分別說自己的語言,如何統一語言,更有效的溝通?
- 文檔:編寫和維護的成本都很高,如何低成本的維護一份有價值的文檔?
Cucumber是一款支持BDD的框架,有助于幫助團隊解決以上問題。
Cucumber支持用自然語言描述業務場景,需要遵循Given-When-Then的格式,這樣就可以容易的對應到自動化測試的3A步驟Arrange-Act-Assert,從而實現業務場景的自動化測試。
Cucumber的理想是將可執行的需求規范、自動化測試和活文檔有機的結合,如下圖所示:
Cucumber的理想
理想很豐滿,現實很骨感。Cucumber在實際應用中的情況又如何呢?
Cucumber的痛點
Cucumber框架實現Web自動化測試包括兩個部分:Feature(特性)文件和Step Definition(測試實現),在實際應用中人們普遍感覺到它的復雜。
- Cucumber特別強調的是協作,Feature文件通常由偏業務的人員來編寫,要求遵循Given-When-Then的格式。這種固定的語法對編寫人員要求較高,寫起來比較費勁,尤其對新人不友好,很多團隊反映要寫出好的Feature文件特別費時費力。
- Cucumber支持多種語言實現測試代碼,但它本身并不能實現自動化,對于Web自動化測試需要跟其他自動化工具結合,比如Selenium-WebDriver。實現代碼不僅復雜,還有著元素定位難、執行時間長、不夠穩定的痛點。
Cucumber-js+Selenium WebDriver實現的代碼長這樣:
Feature定義:
Feature: google Search
Scenario: Finding some cheese
Given I am on the Google search page
When I search for "Cheese!"
Then the page title should start with "cheese"
Steps實現
Given('I am on the Google search page', async function () {
await driver.get('http://www.google.com');
});
When('I search for {string}', async function (searchTerm) {
const element = await driver.findElement(By.name('q'));
element.sendKeys(searchTerm, Key.RETURN);
element.submit();
});
Then('the page title should start with {string}', {timeout: 60 * 1000}, async function (searchTerm) {
const title = await driver.getTitle();
const isTitleStartWithCheese = title.toLowerCase().lastIndexOf(`${searchTerm}`, 0) === 0;
expect(isTitleStartWithCheese).to.equal(true);
});
新一代BDD框架
藍鯨項目曾經就是用Cucumber+Selenium WebDriver實現的UI層自動化測試,由于上述痛點,大家覺得UI自動化測試越來越難寫,我也因此對BDD喪失了信心。
自從遇到了兩款新的工具Gauge+Taiko,我又重新對Web系統的實現基于BDD的自動化測試燃起了希望。
Gauge
Gauge是一款開源的輕量級跨平臺自動化測試工具,它的愿景是用更少的代碼、更少的維護工作實現更多的自動化測試,有如下特性:
- 采用Markdown格式,支持用自然語言編寫Spec,語法自由,編寫工作簡單易上手,不管是對業務人員還是技術人員都很友好;寫出來的文檔格式清晰,很好維護。
- Gauge本身可以實現對Web頁面的訪問和控制,支持多種語言,各種API封裝的很好,代碼實現部分比Selenium要簡單很多,尤其對于編程技能不是那么強的QA來講非常友好,易上手,代碼的可讀性也更強一些。
Taiko
Taiko也是一款開源瀏覽器自動化測試工具,它的特性如下:
Taiko的特性
- 交互式的錄制體驗。Taiko提供類似于irb的REPL,直接輸入命令,可以看到瀏覽器執行結果,同時后續還可以把成功執行的命令直接生成JS代碼,非常方便。
- Taiko不僅提供常見UI自動化測試工具那樣根據Id、name、css、Xpath等方式選擇頁面元素的功能,還提供智能選擇器(Smart selector),支持直接根據顯示的文本來定位各種類型的頁面元素,同時還有支持上、下、左、右這種根據某個元素的相對方位去定位元素的API,很好的解決UI測試頁面元素定位難的問題。
- Taiko采用隱式的等待(Wait)方式,也可以手動設置超時時間以防有些訪問等待時間過長。這種隱式等待相比其他自動化工具需要手動設置等待時間的顯式等待方式要更高效、更穩定。
- 與Gauge的完美結合:Taiko在REPL里執行的瀏覽器操作步驟,可以通過一個簡單的命令直接生產Gauge支持的Step,只需要再去簡單的加上step名稱就可以,操作及其簡單。
Gauge+Taiko的代碼長這樣:
Spec定義
# Google Search
This is an executable specification file. This file follows markdown syntax.
Every heading in this file denotes a scenario.
Every bullet point denotes a step.
To execute this specification, use
npm test
## Finding some cheese
* Goto Google search page
* Google for "Cheese!"
* Page title starts with "Cheese"
Steps實現
step("Goto Google search page", async function() {
await goto("www.google.com");
});
step("Google for <query>", async (query) => {
await write(query);
await click("Google 搜尋");
});
step("Page title starts with <content>", async (content) => {
await title().then((pageTitle) =>{
assert.ok(pageTitle.startsWith(content));
});
});
總結
協作是人的問題,工具可以起到輔助作用,但是不能解決根本問題,過于嚴格的工具缺乏靈活性,反而阻礙了高效協作的可能。
Gauge不強調協作,可以作為自動化測試工具獨立存在,同時又支持高效協作、支持實現BDD,是一款靈活性更好的框架。它的秘密武器Taiko是一款優秀的Web UI自動化工具,兩者的結合堪稱完美,讓需求規范、自動化測試和活文檔的有機結合真正成為可能。
本文只是將Gauge和Taiko跟Cucumber框架從對BDD的角度做簡單的對比,更多的關于Gauge和Taiko的高級特性,請參考【延伸閱讀】部分相關文章。
延伸閱讀
- 說起BDD,你會想到什么:https://www.bylinzi.com/2015/06/04/when-we-talk-about-bdd/
- Gauge:https://gauge.org/
- Taiko:https://taiko.gauge.org/
- Why I chose Gauge over Cucumber:https://medium.com/@divi6.1990/why-i-chose-gauge-over-cucumber-5b3de478d889
- TEST AUTOMATION WITH GAUGE:http://www.santiagomontesinos.com/test-automation-with-gauge/
文/ThoughtWorks 林冰玉