可以檢查單元測試覆蓋范圍的分析工具
分析工具可以幫助程序員構建健壯的單元測試套件。迄今為止,完成這一工作主要有兩種方法:
使用靜態分析以嘗試自動生成單元測試套件
使用靜態分析來確定單元測試套件對程序功能的覆蓋范圍到底怎么樣
目前有幾種試圖自動從代碼產生單元測試的免費工具,但大多數擔任這項任務的免費工具還處于起步階段。其中一些比較有希望的是 JUnitDoclet 和 JUB(“JUnit test case Builder”的縮寫),可在 SourceForge 上得到它們(參考資料一節提供了它們的鏈接)。
關于這些類型的工具,要牢記的要點是:適宜應用于通過測試更新舊代碼。當構建新項目時,它們的作用不大。
為什么會這樣呢?因為新項目應該與項目上的單元測試是一前一后構建的。開發單元測試是構建設計的強有力的方法;針對組件的 API 是在編寫測試時隱式地為它們設計的。此外,以這種風格進行設計向設計師提供了即時的反饋。糟糕的設計將非常難于編寫測試!并且,任何分析工具在確定為程序編寫什么測試這方面,都很難做得象設計師那樣好。
第二種分析工具分析程序及其單元測試,并確定測試能在多大范圍內覆蓋程序。與剛才提到的第一類工具不同,此類工具對每個項目都是有用的。實際上,極端編程團隊可以考慮將此類工具集成到他們的代碼提交過程中。那么,他們不僅能夠防止代碼在通過所有測試之前被提交,而且可以防止代碼在未經測試的情況下提交!不僅懶惰會導致測試覆蓋范圍偏小,錯誤也可能導致同樣后果,因此,此類強制措施對任何技能(和完整性)級別的程序員都有用。
Clover 是一種可以執行此類分析的新的并且特別有希望的工具。Clover 是 Ant 的插件,Ant 是 make 的流行的、全 Java 的替代物。Clover 是商業工具,但它可以免費用于開放源碼項目。
Clover 分兩階段過程進行工作。首先,它在編譯時檢測代碼。然后,在測試時將有關測試的運行信息寫到用來生成報告的數據庫中(通過 GUI、網頁或在控制臺中)。
將 Clover 集成到使用 Ant 的現有項目中很簡單。這涉及調整項目的 build.xml 文件以添加幾個在編譯、記錄測試和生成報表期間檢測代碼的目標。例如,假定我們有一個帶構建和編譯目標的 build.xml 文件。我們所必須做的全部工作是將 Clover JAR 文件放到我們的 Ant 庫目錄中,并如下所示擴展 build.xml 文件(Clover 用戶指南中提供了這些和類似于 Ant 目標的信息;為了方便,我在這里包括了它們):
清單 3. 擴充 Ant build.xml 文件以使用 Clover
<property name="clover.initstring" value="/tmp/mycoverage.db"/>
<target name="with.clover">
<property name="build.compiler"
value="org.apache.tools.ant.taskdefs.CloverCompilerAdapter"/>
</target>
<path id="clover.classpath">
<pathelement path="<CLOVER_HOME>/lib/clover.jar"/>
<pathelement path="<CLOVER_HOME>/lib/velocity.jar"/>
</path>
<target name="clover.report">
<java classname="com.cortexeb.tools.clover.reporters.html.HtmlReporter">
<arg line="--outputdir /tmp/clover_html --showSrc --initstring
${clover.initstring} --title 'My Project'"/>
<classpath refid="clover.classpath"/>
</java>
</target>
特性 clover.initstring 指定了一個文件,有關 Clover 覆蓋范圍的數據將寫入這個文件中。目標 with.clover 用來在執行其它目標(如 compile 和 test)時打開 Clover。clover.report 目標用來接收累積的覆蓋范圍數據并生成報告。
在上面的代碼中,我們將生成 HTML 報告。我們也可以生成文本報告(對于提供給腳本以確定測試的覆蓋范圍是否可接受非常有用)和基于 Swing 的報告。
設置 clover.classpath 是必要的,以便報告生成器目標知道到哪里找到它所需要的所有類。但是,放在類路徑中的第二個 JAR 文件(velocity.jar)只有在生成 HTML 報告時才是必需的。一旦完成了上述工作,可以用以下命令生成 Clover 報告:
$ ant with.clover compile test
$ ant clover.report
是這么簡單。請查閱流行的編碼工具 JBoss 和 Ant 的在線 Clover 報告,以獲取一些樣本輸出。(您可以在參考資料一節找到更多有關這些內容的下載信息和其它信息。)
兩種方法的結合
本文中討論的工具突出了一些可以將程序分析和單元測試一起使用的方法,以提供比單獨執行任何一種方法都更有效的不變量檢測。這些技術只代表了所有可能技術的冰山一角。
將來,其它工具可能會提供更強有力的單元測試能力。例如,類型推斷(type-inference)引擎和優化編譯器可以從現有的單元測試推斷線索、UML 生成工具可以從測試構造各種圖表(不僅是類圖)等等。對于合并這些方法以獲得更佳的代碼構建和故障診斷而言,還存在著巨大的空間可以進行創造性開發和實驗。
請記住每種方法的屬性及其長處:
單元測試能夠演示程序在特定的運行期是如何運轉的;還能說明執行的常用路徑。
分析工具能夠檢查所有可能運行的程序的某些特定屬性。
每種方法的長處都可以用來彌補另一種方法的潛在弱點。
下一次,我們將研究增強的單元測試的另一條路徑,并了解一些新的工具,它們可用于幫助您在 GUI 上開發單元測試。
參考資料
請單擊文章頂部或底部的討論參與本文的論壇。
了解所有關于 Daikon(用 C/C++ 和 Java 前端進行動態不變量檢測的原型實現)的內容,并從 Daikon 網站下載它。
請查閱 Clover user guide 以獲取更多關于該工具的信息,該工具用來發現未被執行的代碼部分,并確定何處的代碼未經足夠測試。
Clover 與 Ant(基于 Java 的構建工具)緊密地集成在一起,如果您還沒有副本,請下載一個。
JUnitDoclet 是使用 XDoclet 的開放源碼單元測試生成工具。
單元測試是極端編程的關鍵實踐。在 Roy Miller 的 developerWorks 專欄 Demystifying Extreme Programming 中了解關于所有極端編程實踐的更多信息。您也可以從 developerWorks Demystifying Extreme Programming 論壇獲得 Roy 關于您 XP 問題的解答。
另一種開放源碼生成工具是 JUB(JUnit 測試用例構建器),可從 SourceForge 獲得。
可以在 JUnit 網站上找到更多擴充單元測試的工具。
Nicholas Lesiecki 在其文章“Test flexibly with AspectJ and mock objects”(developerWorks,2002 年 5 月)中介紹了關于測試用例獨立性的問題,并向我們展示了如何使用仿真對象和 AspectJ 來開發準確而又強壯的單元測試。
Erik Hatcher 在其文章“Automating the build and test process”(developerWorks,2001 年 8 月)中,向您展示了他是如何修改流行的 Ant1.3 和 JUnit 測試框架,以實現構建和測試過程的完整的、定制的自動化。
WebSphere 開發者園地在“Application Quality Assurance:Unit Testing”中提供了一篇關于用 JUnit 進行單元測試的好文章。
“Debugging and Unit-Testing Server-Side Web Applications”也來自 WebSphere 開發者園地,它描述了包含迭代調試和交互式單元測試的服務器端 Web 開發方案。
下載 DrJava,這是一個免費的、輕量型的開放源碼 Java IDE,具有集成的讀-計算-打。╮ead-eval-print)循環、調試器和 JUnit 支持。
閱讀 Eric Allen 的診斷 Java 代碼專欄的所有文章,包括“Designing‘testable'applications”。
在 developerWorks Java 技術專區上可找到關于 Java 技術的數百篇文章和教程。