單元測試和靜態分析通常被看作是有助于確保程序的正確性的互不相干的方法。本文研究了這兩種方法之間的關系,并討論了構成每種方法工作構架的工具如何相得益彰。特別地,Eric Allen 討論了一些可用而又令人興奮的新應用程序,這些應用程序允許您進一步提升您的單元測試。
這是一場古老的爭論 — 哪種方法對產生健壯代碼更有價值:測試還是靜態分析和驗證?您會在程序員的日常工作中聽到這種爭論,尤其是在極端編程(Extreme Programming)論壇上。(請參閱我們由 Roy Miller 主持的XP 論壇。)
支持靜態分析(包括類型檢查)的主要論據是:其結果適用程序所有可能的運行,而通過單元測試只能保證被測試的組件(在測試它們的平臺上)只適用測試組件的特定輸入。
支持單元測試的主要論據是它更容易處理。您可以測試程序的許多約束,這些約束遠遠超出了同期的靜態分析工具所能達到的范圍。
請允許我在此冒昧地說一句:我認為將這兩種工具看作對立的是一個錯誤。每種工具都有助于構建更健壯的程序。實際上,它們可以通過非常強大的方式進行互補。
每種工具都有各自的長處,對于補充另一種工具特別有用:
單元測試能顯示執行的常用路徑,從而顯示程序是如何運行的。 分析工具能檢查單元測試提供的覆蓋范圍。讓我們研究這其中的每個屬性,并討論一些可幫助您將其長處帶給其它方法的工具。
顯示常用執行路徑的單元測試
單元測試套件提供了程序組件的示例用法的穩固基礎。通過檢查測試運行時程序是如何運作的,分析工具可以就開發人員希望在程序中保持的不變量進行試探性推測(就和程序員閱讀單元測試所做的一樣)。
還有另一種方法,其中單元測試可以是一種可執行的文檔形式。在從單元測試的運行中從特殊到一般地推斷出推測性不變量之后,分析工具可以嘗試從一般到特殊地驗證不變量的存在,或者它可以利用可在運行時檢查的斷言注釋該代碼。
在任何一種情況下,在該工具做任何其它工作之前,最好向用戶返回推測的不變量集的報告,以詢問用戶真正想要哪些不變量。順便提一下,如果此類工具向用戶報告了許多他們不想要的不變量,這可能是單元測試出了問題的信號 — 例如,它們不夠一般。
可用這種方式與單元測試一起使用的工具是 Daikon,它是一款來自 MIT 的 Mike Ernst 的程序分析小組的免費的、試驗性的工具。Daikon 分析程序的運行(例如單元測試的運行),并嘗試推測不變量。然后它詢問用戶是否想要這些不變量,并將用戶想要的不變量作為斷言插入程序。
例如,假定我們編寫一個向量(Vector)的適配器,該適配器實現接口Sequence,該接口包含用于檢索元素的方法lookup和用于將元素放在向量末尾的方法insert。方法lookup帶有一個索引i,用來訪問它所包含的向量。
假定該數組的長度存儲在字段length中。通過維護適配器中的長度,我們可以不通知向量本身就將元素從其尾部刪除。
讓我們為這個假想的簡單適配器編寫一個簡單的測試用例:
清單 1. 向量容器中簡單查找方法的測試用例
import junit.framework.TestCase;public class VectorAdapterTest extends TestCase {
public VectorAdapterTest(String name) {
super(name);
}
文章來源于領測軟件測試網 http://www.kjueaiud.com/