前情提要
一直有在收集一些 Kata 用來練習 TDD ,
剛好台中的敏捷社群有這樣的活動, 第一時間就報名參加,
也很幸運的搶到票, 下面是我的記錄與一些心得反饋。
不過我沒有 Php 的經驗, 或許會有一些偏誤。
希望有機會可以整理出一系列的 Kata ,
讓人可以在學習 Coding 過程中將 Testing 變成一種首選(反射行為、自然反應 etc …)
可以參考我之前的 Blog 從 TDD 到 TDD, Todo 到 Test 趨動開發
活動流程
- 主持人簡單介紹, 並邀請大家輪流發言, 說明參加的目的
這個引導技巧蠻好的, 有 Check-In 與 Warm-up 的效果
雖然是還是有人不發言或是後續引發的討論有點少(直接用肯定句結束對話)
但是相信多試幾次是可以改善的 - 主講者介紹題目
- 主講者實作題目
- 拆分「猜數字」與「隨機數」
- 使用 Injection 的技巧
- 解題
- 分組解「隨機數」
- 主講者講解隨機數
- 問問題
心得
看到各地開始有不同的講者來說明 Unit Test 或 TDD 感覺是很棒的,
希望能夠有更多的社群與講者來介紹. 這個工程師的基本技能。
在講解的過程中, 可能是我誤會了, 但是我感覺到講者不確定是不是能講更多,
畢竟測試、單元測試(Unit Test)、測試趨動開發(TDD)的重心都有一些不同,
也許在報名前作一次篩選, 或是同時準備基本
與進階
的教材,
在 Check-In
的階段, 或隨著課程進行由淺入深的介紹,
就以猜數字來說 Injection
也許可以放入進階的部份再介紹,
反而有位與會者在 Check-In
提出的問題我覺得蠻好的。
如何對猜數字這個題目, 進行需求分析, 可惜沒有進一步的研討。
第二部份的猜數字, 包含了隨機的部份, 分組討論我沒有參與到其它組別,
不太確定討論的效果為何? 但是在我的組別是有人完全不說話的,
總之線上活動與會者的參予是非常重要的,
另外在實作猜數字的測試案例時, 講者使用了我們這一組的代碼,
講者似乎有不同的看法, 它將 3 個案例合併成了 1 個,
但是在移除案例時, 並沒有實測可以保護原有案例的部份.
這裡可以處理的更細緻一些.
最後如果能有完整流程的 commits 與錄影的話更好,
當然主辦與講者可能有不同的考量就不予置評了.
用 C# 重新跑一次 Kata
我打算用 C# 重新進行一次這個 Kata 並稍作記錄
規則說明
猜數字是一個經典的遊戲, 分為出題者與答題者,
出題者必需隨機設定一組四碼不重複的數字, 答題者嘗試去猜出正確的數字,
如果答題者猜對數字且位置正確, 出題者必需給一個 A,
如果答題者猜對數字但位置不正確, 出題者必需給一個 B,
如果 4A0B 就代表答對, 遊戲結束.
設計
出題的部份, 我們可以開發給出題者輸入, 或是隨機產生題目,
隨機出題的部份我們可以拉出來當另一個功能, 所以我們先專注在猜數字的邏輯上
先是 A 的邏輯, 表示位置與數字相同, 所以我會需要定位與數字比較
B 的邏輯, 表示位置與數字相同, 這裡我會發現不存在數字比較的邏輯,
而是字串或字符的比對.
大概就這樣, 很簡單來設計我們的 Case 吧
猜數字案例
前設條件:答案為1234
- 5678 應該得到
0A0B
: 目的是產生方法的介面與參數 - 1678 應該得到
1A0B
: 最簡單的方式可以檢查第 1 個數字是否符合 - 1278 應該得到
2A0B
: 最簡單的方式可以檢查第 2 個數字是否符合, 產生重複 - 重構 2、3 案例, 消重複使用
ACounter
作為記錄 - 1238 應該得到
3A0B
: 目的是確定上面的重構有效 - 1283 應該得到
2A1B
: 最簡單的方式檢查是否符合包含 3 - 1243 應該得到
2A2B
: 最簡單的方式檢查是否符合包含 4, 產生重複 - 重構 6、7 案例, 消重複使用
BCounter
作為記錄 - 2143 應該得到
0A4B
: 確認上面的重構有效
出題者的設計
這裡我覺得不適合只使用單元測試, 應該搭配整合測試可以有更好的效果
設計隨機出題
- 每次都是隨機的
- 是 4 個數字
- 4 個數字不重複
隨機答案案例
- 呼叫應得到數字 : 定義介面, 無傳入值, 回傳字串, 但是每個字元都是數字
- 呼叫應得到長度為 4 的字串 : 限制回傳長度
- 重構:使用正規表示式合併兩個 Case
- 4 個數字不能重複
後記
- 將 SetAnswer 由 public 轉為 private,內化為由程式隨機出題(也就是沒有出題者,實務上這層級的改動應參考需求)
- 第二層抽象, 將 SetAnswer 實作包裝一層介面, 抽象為取出不重複數字,
但是將字串職責留在 SetAnswer 之中 - 實作介面, 測試轉移到這個實作之中, 猜數字的測試改用相依性注入作 Mock
- C# 語言特性並沒有對集合的洗牌擴充方法, 抽出這一部份單獨實作, 並使用整合測試進行測試
- 改寫隨機的洗牌方法以符合 Fisher–Yates 的演算法
參考
(fin)