November 15 12:19~13:35
問題
10月份在上【單元測試這樣學就會了實作班】有一位學員問了一個問題…
學員:我的待測程式(System Under Test;SUT)呼叫某個Google API,這個API是需要依據呼叫次數計費的。一開始我想要用Mock Object去mock Google API,後來發現這個Google API太複雜,很難用mock object去處理。後來我還是想了一種方法去測試SUT,但我想請問你對於這個問題有沒有什麼建議?
在Teddy發表自己的看法之前,鄉民們有沒有什麼好建議?
***
測試即設計,設計即測試
這個問題可以從測試與設計這兩方面來思考,從測試的角度,要做到單獨測試(test in isolation),可以用測試替身(Test Double)來取代相依元件。在這個例子中,相依元件就是Google API。問題來了,對於非常複雜的相依元件,不容易用直接用測試替身去取代,除非網路上已經有人寫好相同的測試替身可以直接拿來使用,否則自幹Stub或Fake都需要花費不少心力。
舉個例子,幾個月前Teddy用Java Mail API撰寫寄送郵件的程式,遇到與這位學員類似的問題。Teddy可以選擇用mock object來提供假的Java Mail的Session或Transport物件,但覺得有點太瑣碎後來找到一個用Java開發的in memory的mail server—greenmail,改用它來做測試(等於從mock改成用Fake)。
無論是用哪種測試方法,只要待測程式直接相依於一個複雜的外部元件,都會讓測試變得更複雜。
***
如果可以從設計上動手腳,這個問題應該可以簡化許多。原本的設計SUT直接相依於底層的Google API,這種設計違反了相依反倒原則(Dependency-Inversion Principle)。只要把原先的設計改一下,變成下圖這樣子,將SUT原本直接呼叫Google API所需要介面抽離出來,SUT只相依於這個介面。之後再設計一個Adapter來實作這個介面,實作的方式則可以呼叫Google API。
如此一來,要用假的實作來欺騙SUT就變得簡單許多。
***
迭代與增量的過程
要變成軟體開發高手,不應該將每種技能單獨切開來看:需求就是需求、架構就是架構、設計就是設計、實作就是實作、測試就是測試、維護就是維護。不對,因為這些技能,或者說開發活動,彼此互相影響,設計的好可以互相提攜,設計的不好則是互相「帶賽」。
學習的過程應該是一種迭代與增量的過程。舉個例子,有人說,學好物件導向設計原則就可以不用管設計模式,也有人說學會設計模式就自然懂物件導向原則。這兩者應該是相輔相成,而不是可以誰取代誰。學一些物件導向原則有助於理解設計模式,看了設計模式有助於知道物件導向原則應用的各種不同情境(Context)。
同理,設計能力越好,測試能力也越好,反之亦然。整個開發流程是一個End-To-End的價值鏈,任何一點太弱都會成為開發的瓶頸。
***
打好基礎—物件導向技能
「敏捷開發懶人包:物件導向技能」課程設定目標是希望鄉民們在找工作面試的時候,如果面試官問到物件導向技術方面的問題,能夠具備輕鬆回答的能力。另一方面也為學員的物件導向軟體設計能力打下良好的基礎,對於以後學習設計模式、軟體測試以及軟體架構都有很大的助益。
課程內容依據學員每次上課的回饋稍加調整,對於下列人士特別有效:
- 寫了多年的C程式,突然被叫去學Java、C#或是開發App,不知道如何著手用物件導向觀念作設計。
- 寫了多年物件導向程式,但不確定自己是否用正確的方法使用它。
- 想知道有沒有比較好的方式可以設計物件介面與分配責任。
- 軟體設計如何有彈性地應付改變?
- 物件導向分析與設計到底在講什麼東東?
- 我沒有時間與耐心慢慢學會以上這幾個問題。
▼課程照片
Teddy挑選以下幾個最常使用的重要主題加以介紹,快速幫學員打底,補充身體所缺乏的「物件導向養分」:
- 物件導向基礎觀念
- 封裝、多型、繼承
- 耦合、內聚
- 介面、委託、聚合
- 物件導向與程序導向之優缺點比較
- 依合約設計(Design By Contract)
- 為什麼防衛式程式設計不好?
- 前置條件、後置條件、類別不變量
- 違反合約:例外處理機制
- 合約與繼承
- 依合約設計(DBC)與測試驅動開發(TDD)比較
- 物件導向設計原則這樣聽就懂了
- S.O.L.I.D.五大原則
- 物件導向分析與設計
- 問題敘述
- 環境圖
- 分析模型
- 設計模型
- 實例討論
上課日12月9日(週六) 09:30-14:30,共六小時。
***
友藏內心獨白:基礎功還是很重要。
沒有留言:
張貼留言