l

2014年9月25日 星期四

Test Double(1):什麼是測試替身?

Sep. 22 15:37~16:56

螢幕截圖 2014-09-22 16.49.01

 

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變得困難。

image

  ***

解決什麼問題

在《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,之後將一一為鄉民們介紹。

***

友藏內心獨白:替身也是有區分很多種的。

2 則留言:

  1. 能否講解一下,測試替身可能造成的問題?

    回覆刪除
    回覆
    1. 問題就是Test Double不是真的DOC,所以還是需要撰寫SUT與DOC之間的整合測試。另外,準備與維護Test Double也需要時間。

      刪除