Feb. 22 07:15~09:40
▲本集範例Scenario
Step 1
▼關於Cucumber的基本知識介紹得差不多了,可以開始實作開三聯發票的第一個Scenario。這個Scenario一共有5個step(步驟),首先看到第一個步驟:「Given The VAT rate is 5%」,一開始step definition的實作想法很單純,新增一個Invoice物件,把營業稅5%記錄在它身上。昨天已經介紹過用Percentage類別來支援營業稅用5%或0.05的表示方式,以下的程式碼紅色部分表示語法錯誤,因為Invoice類別和它身上的setVATRate函數都還沒定義。我們眼下的目標就是讓這個step definition至少沒有語法錯誤。
▼實作Invoice類別和setVATRate函數。
▼實作完成之後執行測試案例,第一個步驟通過。之後的例子實作完成之後都會執行測試案例,除非特別狀況否則執行結果畫面就不重複擷取。
***
Step 2
▼第二個步驟:「And the tax included price is 17000」, 把含稅價格設給Invoice物件,當然Invoice身上沒有setTaxIncludedPrice函數所以出現紅色語法錯誤。
▼在Invoice類別加上setTaxIncludedPrice函數實作。
***
Step 3
▼到目前為止都很簡單,鄉民們可能看到快睡著了。請不要轉台,問題即將出現在第三個步驟:「When I issue a company invoice」, 開一張發票。這個步驟說要開一張發票,但是Invoice物件已經存在了,顯然之前那兩個步驟的實作似乎沒有反映需求
▼第三步驟也許應該長成下面這個樣子,透過另一個InvoiceBuilder類別來開一張發票。
▼回頭修改前兩個步驟,step definition變成下面這樣。
▼接下來先新增InvoiceBuilder類別,然後套用move method重構把setVATRate和setTaxIncludedPrice移到它身上。
▼issue函數回傳Invoice物件,並設定Invoice物件擁有含稅價格、營業稅率、營業稅金、未稅價格。getVAT函數用來計算稅金,getTaxExcludedPrice函數用來計算未稅價格,目前都還沒實作。
▼getVAT和getTaxExcludedPrice實作完成之後發現Invoice少了合適的建構函數。
▼實作Invoice的建構函數。
▼跑測試案例,現在前三個步驟都通過了。
***
Step 4
▼「Then I should see the VAT is 810」告訴我們發票的稅金應該是810。
▼在Invoice物件身上實作getVAT函數,
▼執行測試案例也通過了。
***
Step 5
▼最後一個步驟「And the tax excluded price is 16190」。
▼在Invoice物件身上實作getTaxExcludedPrice函數,
▼執行測試案例也通過了。Scenario所包含的5個步驟都通過,整個Scenario也就變成綠燈了。
***
討論
- 看到這裡鄉民們對於BDD—行為驅動開發—應該很有軟體開發「被行為推著走(驅動)」的感覺吧。藉由例子定義行為,然後逐一將例子中所規範的行為透過step definition轉成程式實作。其實這也不是什麼新觀念,和20幾年前的RUP強調use case driven的感覺很像,只不過use case的粒度比起一個scenario大很多,用精實開發的術語來說算是「大批量生產」。BDD或Specification by Example的一個例子粒度很小,算是「小批量生產」,這也是精實開發所鼓勵的方式。當然兩者背後的實作細節差異頗大,不過大方向來看都是藉由「行為」來驅動系統的開發步調(use case也是一種定義系統行為的方式)。
- 另外,這個例子的「商業流程很簡單(幾乎沒有)」,所以鄉民們在step definition看不到什麼商業流程的描述。實做這些step definition的物件也很簡單,也沒什麼複雜的程式邏輯,所以BDD要銜接到TDD的部分在這個例子也看不到。換句話說,還不需要撰寫單元測試來弄清楚InvoiceBuilder與Invoice的行為,因為這兩個類別的行為目前透過step definition已經可以表達清楚了。
- Domain Model目前只有兩個類別,是由BDD的過程所探討出來的,而不是採用傳統OOAD方式先找類別、屬性、方法、關係,然後撰寫程式實作。
- 程式目前還沒重構,可以思考看看有沒有需要重構的地方。
***
友藏內心獨白:這系列的目標快變成從小例子學BDD+TDD+DDD。
延伸閱讀
沒有留言:
張貼留言