對于單元測試的定義,應該分成廣義的和狹義兩種。狹義的單元測試是指編寫測試代碼來驗證被測試代碼的正確性。廣義的單元測試則是指小到一行代碼的驗證,大到一個功能模塊的功能驗證,從代碼規范性的檢查到代碼性能和安全性的驗證都包括在內,視單元的范圍而定義。
1.單元測試由誰來做
關于單元測試應該由誰來做,存在兩種截然不同的對立觀點。一部分人認為單元測試既然是測試的一種類型,當然應該由測試人員負責;另外一部分人則認為,開發人員應該通過編寫單元測試的代碼來保證自己寫的程序是正常工作的。
支持單元測試應該由開發人員執行的人認為,單元測試是程序員的基本職責,程序員必須對自己所編寫的代碼持有認真負責的態度。由程序員來對自己的代碼進行測試的代價是最小的,卻能換來優厚的回報,因為在編碼過程中考慮測試問題,得到的是更優質的代碼,這個時候程序員對代碼應該做什么了解得最清楚。如果不這樣做,而是一直等到某個模塊崩潰時,程序員則可能已經忘記代碼是怎樣工作的,需要花費更多的時間重新弄清代碼,即使這樣也不一定能完全弄清楚,因此修改的代碼往往不會那么徹底。
那些對程序員不應該測試自己代碼的人認為,單元測試應該由測試人員來做。程序員通常都有愛護自己程序的潛在心理,不忍心對程序進行破壞性的測試,而且,程序員也缺乏像測試人員一樣敏銳的測試思維,很難設計出好的測試代碼。
說明:廣義的單元測試不僅包括編寫測試代碼進行單元測試,還包括很多其他的方面,例如代碼規范性檢查,則完全可以由測試人員借助一些測試工具進行。
2.結對單元測試
關于單元測試應該由誰來完成,兩部分人各持己見,爭論了很多年,直到極限編程、測試驅動開發模式(TDD)出現,才使得兩種意見得以綜合考慮。
TDD把單元測試的地位提高到了史無前例的最高點,倡導測試先行、用測試驅動開發。測試是最好的設計,在編寫代碼之前就要把測試考慮清楚,這樣在編寫代碼時才胸有成竹。有人舉了兩個工匠砌墻的例子來說明TDD。
工匠一的做法:先將一排磚都砌完,再拉上一根水平線,看看哪些磚有問題,再進行調整,如圖所示。
工匠二的做法:先拉上一根水平線,砌每一塊磚時,都與這根水平線進行比較,使得每一塊磚都保持水平,如圖所示。
TDD認為應該盡早進行測試,甚至在代碼還沒編寫出來之前就先編寫測試代碼進行測試。如果是這樣的話,很明顯應該由開發人員進行單元測試了,程序員責無旁貸地要擔負起單元測試的職責。
那么,反對這樣做的人的觀點是什么呢?測試人員應該與開發人員進行結對的單元測試,測試人員的優勢是具有敏銳的測試思維和測試用例設計能力,應該充分利用測試人員的這些優點。一種可行的辦法是:把兩種觀點結合在一起,讓測試人員設計測試用例,開發人員編寫測試代碼實現測試用例,再由測試人員來執行測試用例。也就是說,讓測試人員和開發人員結對進行單元測試,如圖所示。
開發人員與測試人員在單元測試的過程中必須緊密地合作,一起討論應該進行哪些測試以及怎樣測試,應該添加哪些測試數據。
開發人員應該向測試人員提供程序的設計思路、具體實現過程以及函數參數等信息。
測試人員根據了解到的需求規格、設計規格來進行測試用例的設計,指導開發人員按照測試用例進行測試代碼的設計。
測試人員運行開發人員編寫的測試代碼進行單元測試以及結果的收集與分析;蛘呃單元測試工具讓單元測試代碼自動運行。
結對單元測試要求測試人員對需求的把握能力要強,而且對設計和編碼過程有基本的認識。開發人員在結對單元測試中應能更好地按需求進行代碼設計,同時也能從測試人員身上學到更多關于測試的知識,以便提高代碼編寫的質量和防止代碼出錯的能力。
延伸閱讀
文章來源于領測軟件測試網 http://www.k11sc111.com/