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