說到單元測試,幾乎所有人都知道,由開發人員完成。可是為什么要進行單元測試呢?
開發人員寫單元測試的時間幾乎和他寫產品代碼的時間相當,因此,當做項目計划的時候,把單元測試考慮進去是合理的。盡管單元測試增加了相當大的開發工作量,看上去開發時間延長了,但實際上對於一個長期不斷改進和維護的項目而言,我們不能忽視級聯效應,要從項目整體來看。
單元測試可以保證最基本的缺陷盡早的發現並解決,因此,用來解決被流轉到后期的測試階段的缺陷時間實際上就會縮短。
而如果問開發人員是否進行了單元測試,他們通常也會說,是的,已經做了單元測試。如果問開發人員,他們的單元測試的步驟,答案很可能是:
開發完代碼之后,實際運行了程序,簡單的做了些功能測試,沒有問題
通過斷點調試進行了代碼跟蹤
不得不說,這么做是對的,也都具有一定的價值,但是並未關注到單元測試最核心的價值,那么,什么樣的測試是有效的單元測試呢?
有效的單元測試需要編寫簡單的、自動化的測試代碼,並且幾乎是和開發代碼同時完成的。
開發人員做單元測試不僅必要,而且重要,每個開發人員都有責任對自己開發的代碼進行單元測試。
那么,單元測試有哪些特點和作用呢?保證代碼質量、更容易發現缺陷、可重復執行、代碼更容易維護、解決缺陷的成本更低
為什么單元測試可以更容易發現缺陷?
因為單元測試是在系統的最低級別進行測試,與別的方法或模塊進行隔離了,因此單元測試的缺陷要比其他層面的缺陷更容易發現並解決。
進行單元測試最主要的原因之一就是解決缺陷的成本更低,因為單元測試中就解決缺陷是缺陷生成到解決最短的周期。
開發人員眼中的測試——把缺陷扼殺在搖籃里
1. 什么是單元測試?
單元測試是由開發人員在開發產品代碼的同時進行的一種獨立測試,驗證其開發的每個代碼單元。
2. 單元測試的目的是什么?
確保程序的邏輯和開發人員對它的預期是一致的。
3. 為什么單元測試應該由開發人員來執行?
對於程序的預期結果,開發人員自己比其他人都要清楚,因此編寫有效的單元測試,開發人員本人是最合適的人選。
4. 什么時候進行單元測試呢?
單元測試和開發產品代碼應該是同時進行,實際上,引入敏捷開發理論之后,更高的要求是測試驅動開發,即單元測試代碼要在產品代碼之前編寫。
5. 單元測試的單元是什么?測試對象又如何理解?
從實用角度講,單元通常是指類的成員方法,也可以是任何具有明確功能、規格定義、明確接口定義,且其規模一般比較小的程序代碼模塊的組合體。
6. 都說單元測試是獨立的測試,那么什么是獨立測試呢?
獨立,是指將代碼從原始程序中隔離出來,盡可能地與程序其他部分或者外界以來隔離,針對各個單元單獨進行測試。
到這里,做個小的總結來把握單元測試的關鍵點:
a. 單元測試記錄預期的行為
b. 每個單元測試針對一個單獨的行為進行測試
c. 盡可能地與程序其他部分或外界依賴隔離
d. 一旦失敗,可以清楚地定位失敗的原因
e. 可以重復運行,且每次運行都有確定的行為,不受上一次運行的影響
f. 可以快速地執行(10秒左右),簡單、實用、高效
g. 有效的單元測試是自動化的
通過以上的介紹,可以對單元測試有了大概的了解,單元測試是什么,為什么要進行單元測試,但是,單元測試需要覆蓋的內容有哪些呢?單元測試,作為白盒而進行的測試,測試包括主要的流程和出錯的分支,以及邊界條件,使用代碼量來衡量測試的覆蓋率。
1. 單元測試的測什么?
單元測試需要保證:覆蓋到所有新開發的代碼、修改過的代碼以及存在的受影響的代碼。
a. 覆蓋代碼所有分支,包括正常路徑和錯誤路徑
b. 覆蓋所有有效的輸入/輸出情況
c. 覆蓋所有無效的或預期以外的輸入/輸出情況
d. 覆蓋所有的日志文件和返回代碼
e. 如果有出錯恢復步驟,確保其正確性
f. 驗證代碼的邏輯正確
g. 在虛擬翻譯的構建環境中通過測試
h. 對敏感代碼要測試其性能(可能需要描述代碼路徑及對數據庫的訪問)
i. 單元測試需要在開發環境中完成
j. 修改所有可翻譯的代碼片段,確保其正確
2. 單元測試的流程?
設計文檔--設計單元測試--創建/修改代碼和相關文檔--對新開發代碼或者修改代碼進行單元測試--代碼審核--集成到代碼存儲庫
3. 單元測試開始的標志?
當接收到一份新的設計文檔或者一個缺陷后,就需要開始考慮單元測試了。
4. 單元測試結束的標志?
代碼完成,解決了已知的問題或已提出解決遺留問題的下一步計划,且經過代碼審核及執行通過單元測試后集成至代碼存儲庫中。
5. 審核單元測試報告:
手動的單元測試報告需要有詳細的步驟,包括使用到的數據集
自動化的單元測試報告不僅要有運行結果,還要給出描述,說明這一組單元測試所測的是哪一部分代碼
接下來了解下測試驅動開發(TDD)
TDD每次針對一個很小的功能點,通常是小到一個單獨的方法。
1. TDD流程:
a. 在實現新功能之前,先考慮代碼的使用需求(包括功能、過程、接口等),為其編寫測試代碼
b. 讓新寫的測試代碼和已有的測試代碼一起運行
c. 為新功能編寫最少的實現代碼
d. 再次讓新測試代碼和已有的測試代碼一起運行,根據運行結果修改實現代碼,直到測試全部通過
e. 在此過程中,積極地對待代碼重構,使底層設計和實現更加優化,使接口更加簡單
f. 重復以上步驟
對TDD的總結:設計代碼-->編寫代碼-->代碼不可運行-->可運行-->重構
2. TDD的目的?
不是為了驗證代碼的實現,而是為了描述一段代碼的用途和用法的設計規格說明,這種描述是無二義的,是可執行驗證的。
3. TDD的優勢在哪里?
TDD要求測試優先,因此可以使得代碼天生具有可測性,也因此保證了幾乎100%的單元測試覆蓋,代碼中的缺陷密度低,有利於更早地發現缺陷,方便調試。
TDD最大的好處,不是最終得到單元測試資產,也不是使單元測試全部通過,而是通過不斷對代碼進行重構,而最終從設計層面對代碼做出改進。
4. TDD與敏捷開發的關系總結: