用 Cobertura 測(cè)量測(cè)試覆蓋率
http://www-128.ibm.com/developerworks/cn/java/j-cobertura/用 Cobertura 測(cè)量測(cè)試覆蓋率找出隱藏 bug 的未測(cè)試到的代碼 ![]() |
![]() |
![]() |
級(jí)別: 初級(jí) Elliotte Rusty Harold, 副教授, Polytechnic University 2005 年 5 月 26 日 Cobertura 是一種開源工具,它通過檢測(cè)基本的代碼,并觀察在測(cè)試包運(yùn)行時(shí)執(zhí)行了哪些代碼和沒有執(zhí)行哪些代碼,來測(cè)量測(cè)試覆蓋率。除了找出未測(cè)試到的代碼并發(fā)現(xiàn) bug 外,Cobertura 還可以通過標(biāo)記無用的、執(zhí)行不到的代碼來優(yōu)化代碼,還可以提供 API 實(shí)際操作的內(nèi)部信息。Elliotte Rusty Harold 將與您分享如何利用代碼覆蓋率的最佳實(shí)踐來使用 Cobertura。 盡管測(cè)試先行編程(test-first programming)和單元測(cè)試已不能算是新概念,但測(cè)試驅(qū)動(dòng)的開發(fā)仍然是過去 10 年中最重要的編程創(chuàng)新。最好的一些編程人員在過去半個(gè)世紀(jì)中一直在使用這些技術(shù),不過,只是在最近幾年,這些技術(shù)才被廣泛地視為在時(shí)間及成本預(yù)算內(nèi)開發(fā)健壯的無缺陷軟件的關(guān)鍵所在。但是,測(cè)試驅(qū)動(dòng)的開發(fā)不能超過測(cè)試所能達(dá)到的程度。測(cè)試改進(jìn)了代碼質(zhì)量,但這也只是針對(duì)實(shí)際測(cè)試到的那部分代碼而言的。您需要有一個(gè)工具告訴您程序的哪些部分沒有測(cè)試到,這樣就可以針對(duì)這些部分編寫測(cè)試代碼并找出更多 bug。 Mark Doliner 的 Cobertura (cobertura 在西班牙語是覆蓋的意思)是完成這項(xiàng)任務(wù)的一個(gè)免費(fèi) GPL 工具。Cobertura 通過用額外的語句記錄在執(zhí)行測(cè)試包時(shí),哪些行被測(cè)試到、哪些行沒有被測(cè)試到,通過這種方式來度量字節(jié)碼,以便對(duì)測(cè)試進(jìn)行監(jiān)視。然后它生成一個(gè) HTML 或者 XML 格式的報(bào)告,指出代碼中的哪些包、哪些類、哪些方法和哪些行沒有測(cè)試到??梢葬槍?duì)這些特定的區(qū)域編寫更多的測(cè)試代碼,以發(fā)現(xiàn)所有隱藏的 bug。 我們首先查看生成的 Cobertura 輸出。圖 1 顯示了對(duì) Jaxen 測(cè)試包運(yùn)行 Cobertura 生成的報(bào)告(請(qǐng)參閱 參考資料)。從該報(bào)告中,可以看到從很好(在 圖 1. Jaxen 的包級(jí)別覆蓋率統(tǒng)計(jì)數(shù)據(jù) ![]() Cobertura 通過被測(cè)試的行數(shù)和被測(cè)試的分支數(shù)來計(jì)算覆蓋率。第一次測(cè)試時(shí),兩種測(cè)試方法之間的差別并不是很重要。Cobertura 還為類計(jì)算平均 McCabe 復(fù)雜度(請(qǐng)參閱 參考資料)。 可以深入挖掘 HTML 報(bào)告,了解特定包或者類的覆蓋率。圖 2 顯示了 圖 2. org.jaxen.function 包中的代碼覆蓋率 ![]() 進(jìn)一步深入到單獨(dú)的類中,具體查看哪一行代碼沒有測(cè)試到。圖 3 顯示了 圖 3. NameFunction 類中的代碼覆蓋率 ![]()
利用 Cobertura 報(bào)告,可以找出代碼中未測(cè)試的部分并針對(duì)它們編寫測(cè)試。例如,圖 3 顯示 Jaxen 需要進(jìn)行一些測(cè)試,運(yùn)用 如果有許多未覆蓋的代碼,像 Cobertura 在這里報(bào)告的那樣,那么添加所有缺少的測(cè)試將會(huì)非常耗時(shí),但也是值得的。不一定要一次完成它。您可以從被測(cè)試的最少的代碼開始,比如那些所有沒有覆蓋的包。在測(cè)試所有的包之后,就可以對(duì)每一個(gè)顯示為沒有覆蓋的類編寫一些測(cè)試代碼。對(duì)所有類進(jìn)行專門測(cè)試后,還要為所有未覆蓋的方法編寫測(cè)試代碼。在測(cè)試所有方法之后,就可以開始分析對(duì)未測(cè)試的語句進(jìn)行測(cè)試的必要性。 是否有一些可以測(cè)試但不應(yīng)測(cè)試的內(nèi)容?這取決于您問的是誰。在 JUnit FAQ 中,J. B. Rainsberger 寫到“一般的看法是:如果 自身 不會(huì)出問題,那么它會(huì)因?yàn)樘?jiǎn)單而不會(huì)出問題。第一個(gè)例子是
我不同意。我已經(jīng)記不清在“簡(jiǎn)單得不會(huì)出問題”的代碼中發(fā)現(xiàn)的 bug 的數(shù)量了。確實(shí),一些 getter 和 setter 很簡(jiǎn)單,不可能出問題。但是我從來就沒有辦法區(qū)分哪些方法是真的簡(jiǎn)單得不會(huì)出錯(cuò),哪些方法只是看上去如此。編寫覆蓋像 setter 和 getter 這樣簡(jiǎn)單方法的測(cè)試代碼并不難。為此所花的少量時(shí)間會(huì)因?yàn)樵谶@些方法中發(fā)現(xiàn)未曾預(yù)料到的 bug 而得到補(bǔ)償。 一般來說,開始測(cè)量后,達(dá)到 90% 的測(cè)試覆蓋率是很容易的。將覆蓋率提高到 95% 或者更高就需要?jiǎng)右幌履X筋。例如,可能需要裝載不同版本的支持庫,以測(cè)試沒有在所有版本的庫中出現(xiàn)的 bug。或者需要重新構(gòu)建代碼,以便測(cè)試通常執(zhí)行不到的部分代碼??梢詫?duì)類進(jìn)行擴(kuò)展,讓它們的受保護(hù)方法變?yōu)楣卜椒?,這樣就可以對(duì)這些方法進(jìn)行測(cè)試。這些技巧看起來像是多此一舉,但是它們?cè)鴰椭以谝话氲臅r(shí)間內(nèi)發(fā)現(xiàn)更多的未發(fā)現(xiàn)的 bug。 并不總是可以得到完美的、100% 的代碼覆蓋率。有時(shí)您會(huì)發(fā)現(xiàn),不管對(duì)代碼如何改造,仍然有一些行、方法、甚至是整個(gè)類是測(cè)試不到的。下面是您可能會(huì)遇到的挑戰(zhàn)的一些例子:
考慮到上面這些以及類似的情況,我認(rèn)為一些極限程序員自動(dòng)刪除所有未測(cè)試代碼的做法是不切實(shí)際的,并且可能具有一定的諷刺性。不能總是獲得絕對(duì)完美的測(cè)試覆蓋率并不意味著就不會(huì)有更好的覆蓋率。 然而,比執(zhí)行不到的語句和方法更常見的是殘留代碼,它不再有任何作用,并且從代碼基中去掉這些代碼也不會(huì)產(chǎn)生任何影響。有時(shí)可以通過使用反射來訪問私有成員這樣的怪招來測(cè)試未測(cè)試的代碼。還可以為未測(cè)試的、包保護(hù)(package-protected)的代碼來編寫測(cè)試代碼,將測(cè)試類放到將要測(cè)試的類所在那個(gè)包中。但最好不要這樣做。所有不能通過發(fā)布的(公共的和受保護(hù)的)接口訪問的代碼都應(yīng)刪除。執(zhí)行不到的代碼不應(yīng)當(dāng)成為代碼基的一部分。代碼基越小,它就越容易被理解和維護(hù)。
在了解了測(cè)量代碼覆蓋率的好處后,讓我們?cè)賮碛懻撘幌氯绾斡?Cobertura 測(cè)量代碼覆蓋率的具體細(xì)節(jié)。Cobertura 被設(shè)計(jì)成為在 Ant 中運(yùn)行?,F(xiàn)在還沒有這方面的 IDE 插件可用,不過一兩年內(nèi)也許就會(huì)有了。 首先需要在 build.xml 文件中添加一個(gè)任務(wù)定義。以下這個(gè)頂級(jí)
然后,需要一個(gè)
用通常運(yùn)行測(cè)試包的同一種類型的 Ant 任務(wù)運(yùn)行測(cè)試。惟一的區(qū)別在于:被測(cè)量的類必須在原始類出現(xiàn)在類路徑中之前出現(xiàn)在類路徑中,而且需要將 Cobertura JAR 文件添加到類路徑中:
Jaxen 項(xiàng)目使用 JUnit 作為其測(cè)試框架,但是 Cobertura 是不受框架影響的。它在 TestNG、Artima SuiteRunner、HTTPUni 或者在您自己在地下室開發(fā)的系統(tǒng)中一樣工作得很好。 最后,
在自己的 Ant 編譯文件中加入了類似的任務(wù)后,就可以通過鍵入以下命令來生成一個(gè)覆蓋報(bào)告:
當(dāng)然,如果您愿意的話,還可以改變目標(biāo)任務(wù)的名稱,或者將這三項(xiàng)任務(wù)合并為一個(gè)目標(biāo)任務(wù)。
Cobertura 是敏捷程序員工具箱中新增的一個(gè)重要工具。通過生成代碼覆蓋率的具體數(shù)值,Cobertura 將單元測(cè)試從一種藝術(shù)轉(zhuǎn)變?yōu)橐婚T科學(xué)。它可以尋找測(cè)試覆蓋中的空隙,直接找到 bug。測(cè)量代碼覆蓋率使您可以獲得尋找并修復(fù) bug 所需的信息,從而開發(fā)出對(duì)每個(gè)人來說都更健壯的軟件。
|
posted on 2005-12-17 11:23 GHawk 閱讀(428) 評(píng)論(0) 編輯 收藏 所屬分類: 軟件測(cè)試