Behavior Driven Development (BDD) 101
(Image source: BDD in Action)
這篇文章主要討論 BDD (Behavior Driven Development)是什麼、BDD會帶來什麼好處?
如何導入、導入的時候要注意什麼、導入 BDD的Python/Java的實作工具有哪些。
軟體開發我們都會希望同時達到兩個目標:
- 做對事 (完成的功能有解決客戶的問題)
- 用對的方式做事 (好的設計、好的架構、設計的軟體有品質)
這個過程研發團隊往往因為時程、壓力、技術等問題,最後兩個目標僅達到一個。
BDD 主要就是透過測試的架構確定完成的功能有達到 “做對事”
接著讓我們討論BDD的預期效益、如何導入、導入的困難與筆者的經驗。
BDD vs TDD vs ADD
首先先討論BDD 與TDD有什麼差異
- BDD: Behavior Driven Development
- TDD: Testing Driven Development
TDD (Testing Driven Development)
TDD 是由 UnitTesting 所延伸的軟體開發方式。
先撰寫測試程式預期的結果,再完成開發功能。當測試程式測試結果為成功時,也就表示功能開發完成。
TDD 要著重在 unitTesting。
每個 unit都可以正常的運作,是不是表是整個功能或是整體功能是可以解決客戶問題呢?
因此 BDD 就誕生!
BDD (Behavior Driven Development)
BDD 從使用者需求分析開始,進行測試程式的撰寫。例如,我們看下列這個使用者需求分析的”情境”Scenario
Given a customer has a current account When the customer transfers funds from this account to an overseas account Then the funds should be deposited in the overseas account And the transaction fee should be deducted from the current account |
像這樣描述系統需求的方式,就是Domain-Driven Design
Given….When…then… 這樣的語法結構稱為 “Gherkin”
- Given:描述該情境的先決條件或是環境的準備
- When: 描述當下的動作
- Then:描述預期的結果
ADD (Acceptance Driven Development)
由於BDD 是從使用者情境與需求出發的開發測試驗證方式,因此又被稱為 ADD。使用者驗收測試。
BDD在整個軟體開發週期
每個專案會決定要達成的商業目標 business goal
根據該目標會有許多的功能要完成 Features
每個功能都會透過 Gherkin的結構語句做一些描述 Examples
開發團隊再根據 Gherkin所描述的情境進一步開發成測試程式
優點是每個”情境”所完成的進度、驗證、是否測試成功等,開發團隊與Product Marketing 團隊都會很清楚。
如何寫一個BDD的情境
舉例來說,我們要完成一個銀行的轉帳功能。
這個功能又分為兩種情境,一個是當餘額足夠時的處理。另外一個是當餘額不足時的處理。
所描述的 user story 就會像這個範例
[pastacode lang=”markup” message=”” highlight=”” provider=”manual”]
Feature: Transferring money between accounts
In order to manage my money more efficiently
As a bank client
I want to transfer funds between my accounts whenever I need to
Scenario: Transferring money to a savings account
Given my Current account has a balance of 1000.00
And my Savings account has a balance of 2000.00
When I transfer 500.00 from my Current account to my Savings account
Then I should have 500.00 in my Current account
And I should have 2500.00 in my Savings account
Scenario: Transferring with insufficient funds
Given my Current account has a balance of 1000.00
And my Savings account has a balance of 2000.00
When I transfer 1500.00 from my Current account to my Savings account
Then I should receive an 'insufficient funds' error
Then I should have 1000.00 in my Current account
And I should have 2000.00 in my Savings account
[/pastacode]
將使用者情境轉成測試程式
完成使用者情境的描述user story 之後,就針對每一個描述轉換成相對應的程式碼。
BDD程式語言實作工具
一般來說每種程式語言都會對應的BDD 實作工具,BDD的工具有Cucumber, JBehave, or SpecFlow or Lettuce
這邊筆者針對 Java/Python 介紹。
Java BDD的實作工具
Java BDD的實作通常會以 Junit + JBehave 或是 TestNG + JBehave
BDD測試結果報告
透過測試結果報告就可以很清楚的知道 user story 中目前開發測試的結果。這是BDD 最大的好處。
這個報告不用太多說明就可以讓團隊成員都理解,因為團隊都是以 user story 定義整個專案要完成的功能。
Python BDD的實作工具
Python 因為本身內建 unitTest 所以會額外需要 behave 或是Lettuce
https://pythonhosted.org/behave/install.html
https://pythonhosted.org/behave/tutorial.html
Robot Framework
Robot Framework 本身結合 Selenium Webdriver + Python unitTest + Testing report + BDD
Robot Framework 因為可以直接針對網頁UI測試,所以也被運用在 Acceptance Testing的領域。
另外Robot Framework 定義許多”關鍵字”,讓整個程式的撰寫更簡潔。
筆者實務經驗
因為 user story的描述需要具體的對應到特定的程式才可以執行,通常 user story 的描述很開放,因此會讓 user story 描述很難重覆被使用。
舉例來說 “account should have a type and an initial balance”
如果下一次Product Manager 寫成 account should have type and balance
雖然對於人閱讀來說意義相同但是電腦就會找不到。
因此,必須要強迫或是規範下一次寫 user story 一定要從之前寫過的資料庫裡面找寫成 “account should have a type and an initial balance”
這樣的規範實務上很難執行,因為要限制人類語言用特定的寫法是有困難的。
因此,如果不採用 BDD方式,筆者建議將測試個案的名稱或是 comment 描述清楚,
讓團隊看到測試報告時,很容易的就可以從測試名稱知道這是哪一個使用者情境的測試。
參考資料
- “BDD in Action”一書
- http://dannorth.net/introducing-bdd/
- The Agile Manifesto: http://agilemanifesto.org
- http://net.tutsplus.com/articles/general/the-principles-of-agile-development/
- http://net.tutsplus.com/tutorials/python-tutorials/test-driven-developmentin-python/