Sep. 22 15:37~16:56
10月初又到了Teddy一年兩次的出國考察時間,每次出國前Teddy都很頭痛,因為除了原本每天一篇文章以外,還要事先把出國這段時間的部落格文章寫好。九月份的周末Teddy都在上課,加上學校開學,又要花時間備課,就更沒有時間寫文章。剛剛看了一下行事曆,有種部落格快要開天窗的危機感。
想來想去,乾脆把上課的教材拿來講好了。這一系列7篇文章將連載在「單元測試與持續整合實作班」所介紹五種Test Double技巧。今天先說明Test Double(測試替身)。
在正式介紹Test Double之前,Teddy要談一下和它的一段「緣分」。話說2004年Teddy和Kay去美國參加PLoP(Pattern Languages of Programs)研討會發表Teddy所整理的幾個e-learning patterns。研討會採用小組討論的方式進行(Writer’s Workshop),Teddy這一組有一個英國人,他發表的patterns裡面,其中有一個就是Test Double。2007《xUnit Test Patterns》這本書出版,Teddy赫然發現原來作者就是當時和Teddy同一組的Gerard Meszaros。沒想到Meszaros居然持續耕耘他的測試模式,最後還整理出版了一本八百多頁的書,真的不容易。
***
測試術語在介紹Test Double之前先介紹兩個測試常用術語:
- SUT:System Under Test或Software Under Test的簡寫,代表待測程式。如果是單元測試,SUT就是一個function或method。
- DOC:Depended-on Component(相依元件),又稱為Collaborator(合作者)。DOC是SUT執行的時候會使用到的元件。例如,有一個函數X如果執行失敗會寄送email,則email元件就是函數X的DOC。
在做單元測試的時候,測試對象是SUT,但因為SUT會呼叫其他物件,使得SUT相依於DOC。換句話說,要測試SUT,DOC也必須存在,這使得測試變得更複雜。例如,請參考下圖的Observer設計模式,假設鄉民們要測試Subject的notify函數,因此Subject的notify函數是SUT,Observer是DOC(因為notify函數會呼叫Observer的update函數)。notify函數所影響的對象是Observer,透過測試notify無法直接觀察到Observer的update函數是否有真的被呼叫,這樣的相依性使得測試notify變得困難。
***
解決什麼問題
在《xUnit Test Patterns》書中提到Test Double可以解決兩個常見的測試問題:
- 如何單獨驗證SUT的邏輯而不用真的使用到DOC?
- 如何避免測試執行太慢?
以Observer設計模式為例,如果鄉民們可以用一個替身來代表真正的DOC(Observer),那麼就可以在這個替身上面動手腳,讓測試變得更簡單。此外,因為替身不是本尊,所以執行速度可以非常快,因此可以解決測試案例執行太慢的問題。
***
Test Double是一種讓SUT可以不依靠DOC而單獨被測試的作法,在實作上有五種Test Double,分別是Dummy Object、Test Stub、Test Spy、Fake Object與Mock Object,之後將一一為鄉民們介紹。
***
友藏內心獨白:替身也是有區分很多種的。
能否講解一下,測試替身可能造成的問題?
回覆刪除問題就是Test Double不是真的DOC,所以還是需要撰寫SUT與DOC之間的整合測試。另外,準備與維護Test Double也需要時間。
刪除