[30天快速上手TDD][Day 24]BDD - SpecFlow Introduction
前言
前面幾篇文章,先介紹了 user story, ATDD ,接著提到了要透過 BDD 來當作 ATDD 與 TDD 之間的橋樑。
這篇文章則是要介紹一下,筆者習慣用的 BDD 工具: SpecFlow 。( open source & BSD license )
藉由 SpecFlow 的輔助,讓讀者朋友可以快速的體會到,用 DSL 撰寫腳本的方式,進而使用 TDD 開始實作系統內容。
回顧
之所以需要透過BDD的工具來輔助我們,是因為:
- 只看用人話描述的腳本,離程式碼太遙遠了。
- 只看程式碼,則太技術面了。
透過 BDD 來結合這兩個部分,讓中間轉換的成本可以降的更低,並且讓使用者、開發人員、測試人員溝通的基底一致。
SpecFlow
- SpecFlow 是一套 open source ,且 under 在 BSD license 。
- 可直接與 Visual Studio 整合。
- 專案若需參考到 SpecFlow 的組件,則可以直接透過 NuGet 來下載。
- 若想了解原始碼,則可以到 Github 上下載。
相關網址:
這邊附上官網對 SpecFlow 的介紹:
SpecFlow also supports the concepts of Acceptance Test Driven Development (ATDD) and Behavior Driven Development (BDD), which are often used synonymously with Specification-By-Example.
讀者就不難了解,為什麼筆者會選用這一套工具了。
建立第一個 BDD 專案 with MS Test
官網的範例大部分都是使用 NUnit 來示範,甚至預設也是使用 NUnit 的設定,所以我就不對 NUnit 的設定多做介紹。這一篇文章要介紹,怎麼透過 MS Test 來進行 BDD 的測試。
當安裝完成後,請新建立一個『測試專案』,例如 TestAtmOperation:
建立 SpecFlow Feature File
如果您已經有安裝好 SepcFlow ,那麼在測試專案上,新增一個 item ,即可看到多出了三個項目類型:
- SpecFlow Event Definition
- SpecFlow Feature File
- SpecFlow Step Definition
這邊先選擇 SpecFlow Feature File ,並命名為 DrawMoney ,代表『提款』的 feature 。
接著在方案中就可以看到 DrawMoney.feature ,打開它之後,會看到預設的 template 內容:
接著,先新增放置 production code 的 Library,並在測試專案上,設定好參考。
接著給它勇敢的建置下去,碰!跳出 21 個錯誤,都是 DrawMoney.feature 找不到 NUnit 的錯誤。
安裝 NuGet Package Manager
這邊要先請各位安裝一下 NuGet Manager,一切會快樂很多。
加入 SpecFlow 參考
裝好之後,在測試專案的參考上,滑鼠右鍵,選擇『管理 NuGet 套件』
接著搜尋『SpecFlow』。
給它安裝下去。會看到參考中多了 TechTalk.SpecFlow ,而且多了 App.Config 檔案。
更改 SpecFlow 設定檔,改成 MS Test
打開App.Config,會看到 SpecFlow 的設定區塊已經加上去了, SpecFlow 很佛心地連 config 設定的網址都附上來了。
點 hyperlink 可以看到第一個區塊,就是跟我們說,怎麼將 unitTestProvider 設定成 MS Test 。當修改設定檔完成後, SpecFlow 會跳一個提示,問你是否要重新產生 feature 對應的測試程式,在這邊也就是我們的 DrawMoney.feature.cs 。按『是』就對了。
到這邊,基本上就設定完成了。
Run ! Test Run ! Test Run !
接下來跑一下測試,(我習慣的 hotkey 是 Ctrl+R, A),基本上我是拿執行單元測試來當作 build 用,以確保每次 build 程式碼除了符合編譯器規定,也能通過單元測試。
測試結果與相關訊息,如下圖所示:
測試結果出現了一個『結果不明』的狀態,這代表了 feature 檔,透過 DSL 所建立的 Unit Test 檔案內容中,相關的設定還沒初始化完成。
而在錯誤訊息中,出現了很有趣的東西,看到了嗎?
第一行的 Assert.Inconclusive,No matching step definition found for one or more steps ,代表測試過程中,已經透過 feature 檔所產生的測試程式,來尋找有沒有對應的 step 檔案。且後續的訊息更揭露了, step 檔案中,應該要有的 function 內容。而且這些內容與 feature 檔案的 Scenario 是相吻合的。
接下來,就是要滿足測試程式所期望的測試結果。
建立 SpecFlow Step Definition
剛剛的測試結果提醒我們, feature 沒有對應的 step 定義,所以接下來就新增一個 Spec Flow Step Definition ,取名為 DrawMoneyStep 。
該檔案預設的 template 內容如下,該有的說明也都在註解中了:
已經滿足了原本的測試結果,再跑一下測試。測試的結果仍然是『結果不明』,但細部資訊已經不同了。
到這邊為止,其實就是 BDD 的起手式完成了。
說明
回顧一下預設 Feature 檔案的內容:
Feature
預設的 feature 檔案內容中, Feature 區段的意義:
- 定義了一個『加法器』,也就是 Feature: Addition。這邊可以把 Feature 當作 User Story 的名稱。
- In order to avoid silly mistakes:代表這個 User Story 的價值,也就是 Business Value。
- As a math idiot:代表了 User Role 。
- I want to be told the sum of two numbers:代表了目的,也就是 Goal。
Scenario
而 Scenario 的區段,就更直覺了:
- Scenario: Add two numbers。代表這是一個描述『將兩個數字相加的 Scenario 』。
- Given 關鍵字:可以當做環境設定,可以把它視為 3A 裡面的 Arrange 。
- And 關鍵字:則用來連接上一個子句,以這邊的例子來說,就是環境設定包括了:『I have entered 50 into the calculator And I have entered 70 into the calculator』。
- When 關鍵字:觸發的動作,可以把它視為 3A 裡面的 Act 。
- Then 關鍵字:代表應該出現什麼結果,可以把它視為 3A 裡面的 Assert。
user story的部份,可以參考前面的文章:[30天快速上手TDD][Day 20]ATDD - User Requirement
雖然把 Scenario 中的關鍵字與 3A 原則(可以參考前面的文章: [30天快速上手TDD][Day 3]動手寫 Unit Test )作結合,但不代表只有 Then 裡面,可以加上 Assert 。如果大家有用 DbC (Design by Contract) 的方式設計程式,就應該知道,在每一個步驟、環節,適當地透過 Assert 來檢查 Pre-Condition, Post-Condition(Pre-Condition, Post-Condition,很熟悉吧,請參考前面提到 use case 的部份,請見 [30天快速上手TDD][Day 20]ATDD - User Requirement),會讓程式碼更加健壯。
有了以上的概念,再來看預設的 Step 檔案內容,就不會太難懂了。
BDD 結束,接下來下一篇,我們來 TDD 吧!
小結
這篇文章只是快速簡單的介紹,該怎麼安裝 SpecFlow,並針對最重要的兩種檔案: Feature 與 Step 的內容作個說明。以下針對對應關係、開發流程順序以及可產生的效益作個歸納說明。
對應關係
簡單的對應關係:
- Feature 檔,對應到 user story
- Feature 檔中的 scenario ,則對應到 acceptance test cases
- Scenario 中的 Given, When, Then,則對應到測試的 3A 原則:Arrange, Act, Assert
最終型態應該是, Feature 與 Scenario 即為系統開發的 spec ,開發人員只要依照這樣的 spec 完成功能,通過測試,即可驗收。
而這一份 spec ,測試人員與開發人員一定可以看懂,甚至於使用者也看的懂,因為是用 DSL撰寫的。(甚至可以寫成中文)。
開發流程順序
倘若透過一些設計與輔助,開發流程可以變成下面這樣:
- 一開始的 user story 與 acceptance test cases ,可能可以透過 Fit/FitNeese 之類的工具,讓使用者透過熟悉的工具,如 excel, wiki 等介面來輸入 user story 與驗收測試案例。
- 接著再把這些資料轉換成 feature 與 scenario 。
- 再由開發人員依據 BDD specflow 透過 T4 產生的 step template 。
- 再依據 step template ,開始進行 TDD ,所有測試都是從使用者需求的系統行為驅動。
效益
如此一來,就真的可以:
- 把各角色、各階段的轉換成本降到最低。
- 大家可以用同樣的語言溝通。
- 彼此的基底就是這些會說話的測試案例,以及隨時可以單鍵執行的測試程式。
- 測試案例還可以當作是系統與物件的說明書。
- 需要接手、維護的人員,只要看的懂測試案例,就可以知道怎麼用。
- 加上有豐富的測試程式保護,所以重構與需求異動時,不用擔心改這壞那的情況。
備註
- 這篇文章只先用預設的 Feature 與 Step 來設計『加法器』,請原諒我文章中命名與 BDD 檔案內容暫不相符。
- SpecFlow 若要安裝 1.9 以上的版本,要先移除 1.8 的版本,如果讀者朋友之前已經裝過的話。
- 目前 SpecFlow 版本是 1.9.1 ,筆者建議安裝 1.9 以上的版本,比起 1.8 版本多了不少功能。目前 VS2012 執行 Scenario 不會有問題,但與 VS2010 的機制有點差異, VS2012 預設會執行該 feature 檔中 所有的 scenario ,在 VS2010 則是只會執行游標 focus 的 scenario 。
blog 與課程更新內容,請前往新站位置:http://tdd.best/