Mock技術在測試領域的應用
什麼是Mock?
我想Mock這個詞對於經常寫單元測試的開發來說肯定不默生。如今在測試驅動開發的思想下,單元測試被推到了一個很重要的位置。因為它是直接能覆蓋到所有程式碼邏輯的最佳測試手段。在單元測試的過程中,複雜業務邏輯需要跟外部資源通訊互動,例如獲得一個數據庫連線物件,例如傳送一個HTTP請求並獲得實時回覆的一些資料等等。當複雜業務從這些與外部物件的互動開始時,單元測試往往需要藉助給力的Mock技術,來模擬這些外部環境和物件。最終目的是讓待測試業務程式碼能夠順利的執行下去完成單元測試的驗證。因為這樣的需求,優秀的Mock單元測試框架也開始流行起來,例如MockITO、PowerMock、Mock Framework等。
Mock在測試中的作用?
Mock技術真的只能發揮在單元測試上麼?在“Google如何做測試”一書中,也提到了Google使用Mock的思想,由於測試工作從專案啟動之初就已經開展,許多功能程式碼完成的先後順序各不相同。也許即使是同一個業務功能,在UI完成了之時,後臺還沒完成(或者正好相反)。那麼一定要等到兩者都完成並且聯調完成了之後,測試工作才能展開麼?試想一下開發是怎麼做的:他們一定會事先約定好一個通訊格式,比如HTTP協議,後臺與前端、或者後臺與其他後臺模組,通過HTTP協議通訊,約定好傳送欄位的含義和後續的邏輯,將雙方的開發任務解耦合隔離開來,並行下去。等到真正聯調的時,只要約定未被打破且嚴謹,基本上都只需要很少得時間就可以組合到一起交付給測試。
同樣的思路,如果用在功能測試上,試想一下如果測試從設計之初就參與進來,他們也瞭解模組之間、前後臺之間的通訊格式和欄位的詳細含義。協議的格式等等。那麼也可以在測試中Mock後臺、Mock前臺、或者Mock業務邏輯的通訊物件。將複雜的業務邏輯測試工作都隔離開來,獨立測試。當然這並不是說,不需要在真實環境中測試,但是真實的軟硬體環境並不是所有情況測試都能遇見並且創造出來的、通訊協議的各種情況也不是真實環境都能遇到的,那麼Mock所帶來的好處就是可以全路徑的來覆蓋到每一種可能出現的情況。敏捷快速的隨著開發的進度並行的開展測試。
舉兩個具體的例子吧:
1. 筆者之前負責的專案需要跟各種無線基站Radio通訊,我們不可能花幾百萬美金去買各種型別價格不菲的基站放到實驗室一臺一臺測試。再說就效能壓力測試上也不可能真的去弄到幾萬臺裝置。所以我們的做法就是了解產品與基站通訊協議之間的詳細互動格式,協議細節(SNMP),並由測試團隊負責開發這樣的Mock工具,在產品到真實環境去除錯之前,都是使用這個Mock工具來模擬出通訊基站物件的各種資料和各種行為,從而覆蓋產品的所有邏輯驗證。(我們使用了基於Java的SNMP4J開源框架,並藉助了幾臺真實基站上通訊取下來的樣本資料)
2. 另外一個例子就是筆者現在的專案,需要跟PC、筆記本、伺服器通訊採集並監控到它們的硬體資訊。很難想象,如果不使用Mock技術每次測試的時候,我們如何去製造音效卡、網絡卡的丟失、各種伺服器記憶體、CPU的增加更替、如何找到大量伺服器測試它們的硬體資料呈現。瞭解產品的通訊協議和資料格式之後,我們能隔離前後端的邏輯,利用模擬上報的資料至少能讓我們專注測試前端對這些資料的展現和控制邏輯。
Mock不是銀彈
測試不管是單元測試還是功能測試都可以使用Mock技術來提高效率,但正如之前在InfoQ上看到的一篇文章講Mock技術的文章(http://www.infoq.com/cn/articles/thoughtworks-practice-partvi)提到的:Mock技術不是銀彈,並非完美。我們不應該依賴它,而是應該合理的去使用和把控它才能最大程度的幫助到測試工作。
按照筆者個人的理解,如何把控使用Mock技術,至少要遵循幾個前提:1. 是否瞭解Mock真實程度?這需要測試人員對產品的架構、通訊協議、資料格式都瞭如指掌。2. 拿來主義直接使用現成的Mock框架也許能快速的帶來效益,但從長遠觀點來看,最適配每個公司產品的Mock工具,最好能由公司內部發起並維護,當然最好是測試團隊來完成,因為測試人員都應該是產品的專家,這就需要他們也有不錯的開發和編碼、架構能力。