昨晚是AgileChina 2011的Open House活動,我是Coding環節的志工。 Coding環節主要是想讓參加的開發人員體驗一下結對程式設計、測試驅動開發、重構的過程。我們準備了四個不同類型的程式設計題目,公司會有八、九位同事和參會的同行一起來體驗這個過程:
Time Sheet
超市結帳
源代碼行數統計
21點遊戲
整體說來,活動還是挺成功的,只是出現兩個小插曲:
1、公司為了這次活動新買的鍵盤和滑鼠,可是敲起來太沒手感了,鍵盤上的鍵都是平平的。有位參與者可能是不太熟悉鍵盤總是把回車敲錯成斜線很多次。
2、系統的鎖定螢幕快速鍵與IDE的格式化程式碼快捷鍵相衝突,導致我兩次敲錯了鎖定螢幕了,而且機器也不是我的,要找其他同事來幫忙輸入密碼,汗死。
在最後一輪Pair當中,有同學問:為什麼不使用assertEquals呢?我看到你們都是用assertThat,好像不太提倡用assertEquals和assertTrue等。
當時因為活動快結束了,我們要去拍合照,所以簡單的回答了一下。這裡再詳細回答一下這個問題。
我們想從斷言裡得到什麼
對於測驗裡的斷言,我們想從中得到什麼呢?測試失敗後只顯示一個紅色條並不是我們想要的,除此之外我們還想從測試中獲得一些資訊:
1、哪裡的測試失敗了,有程式碼行麼?這個所有的斷言都能提供這個功能
2、測試為什麼失敗 這個就很難界定了。大部分斷言都能提供類似這種功能:
期望的結果 vs 實際的結果
但是不同的斷言提供的資訊卻不盡相同。還有一些問題,用簡單的相等之類的斷言是很難比較的。而且,斷言還有一個非常重要的作用:文件。也就是,當你閱讀測試程式碼時,看到斷言你就像是看到了所有的期望。而且非常明了的期望。
實際的例子
看看assertThat的第二個參數,它接受的是一個Matcher
1: assertThat(userDAO.findAll(), hasItem(expected));
如果用其他斷言該怎麼做?
1: assertTrue(userDAO.findAll().contains(expected));
好,這就是問題所在,如果上面兩個斷言都失敗了,第一個斷言的失敗信息將是:
期望結果中包含expected….
但是實際上…這裡會把findAll返回的所有user都印出來
而第二個斷言呢?是這樣的:
期望為true,實際上為false
請問哪一個比較可靠一點?顯然第一個斷言的失敗訊息更利於我們尋找問題。
對於文檔化,我們再來看這麼一個要求:斷言返回的用戶列表裡不包含給定的用戶:
1: assertThat(userDAO.findAll(), not(hasItem(expected));
是不是很清晰明了,讀這個斷言你不會感覺到你是在讀代碼,就好像在讀Spec。如果用其他的斷言:
1: assertFalse(userDAO.findAll().contains(expected));
都沒有前一個更好的文檔化。
當然,對於某些API回傳的就是true或false的,或是回傳的就是個單值的,你也可以用其他的斷言,沒有太大問題。例如這個:
1: assertEquals(userDAO.findBy(id), expected);
啊,什麼?你說我用錯了,為什麼啊。查查參數說明,發現原來期望的值應該放到第一個參數,而實際值應該放到第二個參數。好無奈啊,我記憶力不好,總是會弄錯這些,幸好我們有了assertThat:
1: assertThat(userDAO.findBy(id), is(expected));
你還會弄錯?
以上就是assertThat, assertEquals, assertTrue的內容,更多相關內容請關注PHP中文網(www.php.cn)!