不要為數據持久層編寫單元測試
為增強自信心而寫代碼
關于單元測試,其作用我認為更多的是增強開發者的信心,以及作為代碼的執行文檔(額外的效果)。也就是說,編寫單元測試首先是開發者的責任,其次單元測試的粒度由程序員的自信心決定。
"老板為我的代碼付報酬,而不是測試,所以,我對此的價值觀是——測試越少越好,少到你對你的代碼質量達到了某種自信(我覺得這種的自信標準應該要高于業內的標準,當然,這種自信也可能是種自大)。如果我的編碼生涯中不會犯這種典型的錯誤(如:在構造函數中設了個錯誤的值),那我就不會測試它。我傾向于去對那些有意義的錯誤做測試,所以,我對一些比較復雜的條件邏輯會異常地小心。當在一個團隊中,我會非常小心的測試那些會讓團隊容易出錯的代碼。"
--XP和TDD的創造者Kent Beck如是說。
由過去的經驗,我認同上述的觀點,并且認為不應該將單元測試作為銀彈。甚至項目經理應該忘記有單元測試這回事,干脆把那當做程序員的樂趣就好了,然后該有的測試流程和規范必須要求到。
不要違反原則
單元測試需遵守的關鍵原則是:
1、單元測試應該是可重復的
2、單元測試應該是獨立的
3、單元測試是快速執行的
以下為一個壞的例子。
部門的技術主管一直希望找到一種方法可以普遍提高開發人員的代碼水平,以及減少bug和改善設計,這恰恰是單元測試所擅長的。所以我們配合持續集成的實踐,在后來的項目中嚴格要求單元測試。
不得不說,在經過一段時間的抵觸后,大家還是非常喜歡的。因為我們的產品清單上有專門的單元測試時間,并且大家也開始嘗到甜頭--容易犯的小錯少了。
但是在我們還來不及歡呼的時候,問題出現了,而且很棘手。
我們的項目大都是關于數據存儲的,比如簡單的新增、復雜的查詢、顯示報表等等。而我們的單元測試其實就是冒煙測試,并且還是不合格的單元測試。原因是我們使用數據庫的數據作為輸入,眾所周知,這些數據很容易被修改,故我們的單元測試是不可能具有可重復性。另外,我們的單元測試也不是獨立的,因為我們非常依賴數據存儲層。
從以上的描述,你可能猜到,沒錯,我們的開發人員大多都很初級,經常犯得錯誤就是關于sql的編寫,ibatis的使用語法之類的錯誤。也就是說他們最不自信的地方就是語法或者工具的使用。
讓單元測試變成可重復的相對簡單,使用dbunit之類的工具可以輕松的達到,即使這個工具有時也會出錯,比如oracle的Large Objec類型就會報錯。但是對數據存儲層的依賴就不能避免了,因為這恰恰是我們要測試的。而相比時間而言,前兩個因素又顯得不那么重要了。
在項目中,我們對每個dao層的方法都寫了單元測試,有的單元測試花費的時間甚至比寫代碼的時間要多。結果是我們的代碼確實是可用的,但是時間卻比想象的多得多。比如由A來編寫接口,然后由另外一個人B來編寫頁面,然后由B調用A的接口。花費的時間=編寫接口+編寫頁面+2*調用接口時間(這個名稱不怎么好,但是在海沒有發現合適的名稱時,還是讓我們暫時使用它吧)。調用接口時間是指兩個人座到一起,A告訴B如何調用他的接口的時間,加上剛好出了問題,A為了方便直接在B的電腦上修改花費的時間。這里的時間都是兩份的。
而我們的項目執行一次單元測試至少要10分鐘左右,而且還會報錯,因為不可重復性,有時它可以執行成功,有時它并不能。現在我們要花費的時間變成編寫接口+編寫頁面+2*調用接口的時間+n*10分鐘。
之前說了,我們要求單元測試時為了保證接口是可用的,單元測試并不是唯一的方式。假設我們啟動項目(5分鐘),點擊頁面進入頁面(每次0.5分鐘),然后出錯查看信息,解決問題(M分鐘)。相比之下,使用單元測試則是啟動10分鐘,出錯,設置打印信息,然后啟動(10分鐘),再設置打印信息。直至發飆。。。
現在,你應該知道我們的痛苦了。
posted on 2014-08-05 09:29 順其自然EVO 閱讀(226) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄