緣起
會有這次分享,最初的原因是因為真實在團隊成員開始著重寫 unit test 後,而test達到一定的量時,一些問題便慢慢浮上水面來。例如:
- 有人覺得功能開發很趕,來不及補test
- 有人不曉得自己的unit test 是否足夠
- 有人會直接使用 PowerMockito 來測 private function的正確性
- 大家的test function 越來越多,但命名卻沒有一定規則,難以閱讀
- 大家的測試邏輯也不太一致,有人會在同一個test裡測了五六種不同的input,即一個test測五六個情境,這樣的設計,如果又沒有加上適當的註解對每一段進行切割分類的話,基本上就只能從input跟做assert的程式碼來猜測這一段是為了測甚麼情境,但往往這是很累人的閱讀
- 到底哪些class或function是不能沒有unit test的?而哪些範圍又可以用覆蓋率較大的 integration test 取而代之?
以上遇到的問題,撇除第1跟2之外,其他的問題基本上就是會造成 test 日後難以維護的情況
進一步的,難以維護日後就會不想維護,想要拔掉,那code的穩定與品質性要靠誰來維護呀?
因此,我自己試圖整理一個talk,想要跟team裡面的大家一同溝通討論這些在寫test 中遇到的問題
一方面是整理自己在寫測試上的一些心得,二是想聽聽大家有沒有其他想法。
爾後,我便針對「如何寫有效的unit test」跟「Test的團隊共識」這兩件事分別在兩次code review的過程中跟大家分享,反應基本上不錯,而「Test的團隊共識」這件事更屬於應該是團隊一起決定的事情,大家都有很積極地發表一些意見。
由於分享後獲得的評價不錯,主管們便鼓勵可以致技術社團上分享,藉此與公司外的人促進交流。
於是便有了這次 AgileMeetup 活動的安排了。
第一次技術社團分享 - 感想是「既緊張又興奮」
對於這次活動會來參與的人有哪些其實我也不太清楚,不過應該都是多少有參與Agile社群裡的一些有志之士吧。
由於這次分享的內容主要以觀念為主,但又怕大家對於內容的深度有過度的期待,所以把題目定為「淺談」。
當天仍是十分緊張,Terry跟大家也在不斷地幫我打氣,「緊張就輸了」
John 卻說要留兩個位置給大人物的,害我更加緊張。
離開始時間7:30pm剩下不到十分鐘,發現2位身穿紫色T-shirt的熟悉面孔出現了
大牛 Daniel 跟 Vince都來了,真的是受寵若驚。
Daniel是啟蒙我當個成年人的可敬人物,大神來了,雖然緊張依舊,但其實心中確實有些亢奮
演講開始後,先告訴大家我不是台灣人,讓大家有做好聽奇怪口音的準備了。
slide我已經分享到 SlideShow 上了,過程就不多贅述了。
問題彙整:
演講分享,最開心的還是可以跟台下的大家互動、提問回答,分享意見與獲得回饋。
在分享的中途與結束後,都留了時間讓大家提問,出乎意料之外的多人提問。
以下把比較有印象的問題彙整一下:
- 甚麼時候該針對 legacy code 寫unit test?
- 怎麼針對無法寫 test 的 legacy code 進行 refactor ?
- 你有講到不要按著product code來寫 unit test,在 extreme programming一書中提到可以把順序調過來,是可以先寫 test 嗎?
- 針對restful api這樣的系統架構,如果controller就是純粹把service的output再往外丟,那還有需要針對controller寫unit test嗎?
- 在一個function裡,有invoke很多外部component,如果要test這個function,需要進行大量的mock,那是否只用powermockito這類的library,嘗試去測其中重要的private function就好?但又怕之後有稍為rename private function的話, test又會壞掉
當中其實也有些蠻值得討論的議題,之後聊到落地實作時再聊聊
自己的程式自己測,「品質」絕對是自己堅持出來,而不是別靠人測出來的
Richard 在 FB上分享了這樣的感想:
今天很多社群朋友來公司聽聽我們TenMax
的工程分享,感覺注重 工程師自己寫測試/嘗試重構的案例愈來愈多了,問的問題也都比幾年前進階,所以也難怪這個主題的票仍然一個早上就售完!
很樂見這種工程文化在台灣也逐漸被重視,且有人戮力在實踐。
隨著敏捷文化在台灣開始被深耕,自己的程式品質自己要用測試來保證,這樣的概念似乎越來越被重視了,Developer跟QA的邊界也不再是清楚的楚河漢界了。
然而,大家的提問內容,針對legacy code的問題佔了大多數,
顯然,Legacy code真的是大家在開發新功能與維護舊功能上都會踫到的痛
Legacy code 到底該不該refactor?
其實我們團隊針對 legacy code 也是經歷過一番的掙扎與探,也有過一些嘗試與失敗的經驗。
但是處理 Legacy code, 基本的原則就是「不要為了無謂的程式潔僻而重構」
既然是legacy code,證明它已經存在著好一陣子了,系統運作上也應該是正確的
如果不是因為feature change要踫觸到這一塊legacy code的話,基本上就沒有必要去冒險與花費成本進行重構
因為legacy code又遇上沒有test的話,重構的成本是很大的,
- 要先重新理解這段code影響到的scope
- 確認SPEC
- 加入 test case
- 重構
但也因為是legacy code,在系統上造成影響的範圍一定不小,
當然我想大家應該也是遇到需求才會問這樣的問題,
也該 legacy code 會是討論測試實戰時的重點議題。
Team convention 不等於機械式的coding
對於test code的團隊共識是這次分享的其中一個重點概念,
但我想要重申一下,這樣的convention定義出來的目的,
並不是為了讓大家跟著誰寫出一樣的code,又也不考驗大家的英文水平
大家的邏輯都會有差異,coding風格差異更大
可讀性 是 test code裡最重要的,所以加快閱讀速度也是可讀性要達到的目的之一
因此,convention 最大的意義是團隊的共同認知,卻不侷限於我舉例的規則上。
感想
第一次進行技術分享,我覺得自己的收獲不比台下的聽眾少,因為在準備過程中我花更多的時間是去理清我還無法好好描述的觀念與問題
也因為被不斷的提問,讓我跟我的團隊回顧起更多還存在於我們程式碼裡的問題。
接下來還有好幾個主題想要跟大家討論分享。
- TDD如何入門
- Unit test實務中常用的驗證技巧
- Legacy code的考量與重構
我會再花些時間整理,若有機會的話再來跟大家做個經驗之談。
對於大牛Daniel的驚喜參與還是很受寵若驚,
本日針對問題「請用一句話描述敏捷」的金句回答:
不要臉
P.S. 再次感謝過程中各位的幫助
主辦人 David
當天的大忙人 John,也幫我拍了很多照片的快梗王
主持人Terry,下午還參與主持我們team的retro
還有 TenMax 從鼓勵、給予議見、陪伴、到打氣的各位一同成長的伙伴們。
最後當然是感激有來參與的,讓台灣的軟體開發更上一層樓的在場各位。