不論TestCase寫的多么的好和完善,要想確保被測試的代碼每一行都被執(zhí)行,仍然是非常困難的。為了獲取關(guān)于這方面的信息,我們可以使用JCoverage。
使用目的
JCoverage正如其名,主要用于代碼的覆蓋測試。通過在被測試類的二進(jìn)制文件中添加相應(yīng)的指令,再配合junit,jcoverage可以給出被測試類的代碼覆蓋率,并給出測試過程中哪些語句被執(zhí)行,哪些沒有。通過這些信息,我們可以了解測試代碼的測試質(zhì)量,以及被測試類中哪些語句需要特別的關(guān)注(即那些未被覆蓋的語句)。
當(dāng)前的版本是1.0.5,可以從www.jcoverage.com/downloads.html下載。在實(shí)際使用時,需要將jcoverage用到的類放到對應(yīng)的classpath中。在這個版本中它所依賴的外部類以及版本:
- bcel 5.1 http://jakarta.apache.org/bcel/
- log4j 1.2.8 http://jakarta.apache.org/log4j/
- getopt 1.0.9 http://gnu.org/
- oro 2.0.7 http://jakarta.apache.org/oro/
用法
1. jcoverage可以和ant配合使用,使這一過程自動化。基本用法:
- 編譯被測試類和相應(yīng)的被測試類的junit代碼。
- 使用<instrument>,將jcoverage的指令加入到被測試類的二進(jìn)制文件中。為了保證這一過程能夠有效,請?jiān)诰幾g被測試類時,設(shè)置<Javac>的debug屬性設(shè)為yes。
- 執(zhí)行junit代碼進(jìn)行代碼覆蓋測試。這一步需要注意的是,需要將被注入指令的測試類要早于單元測試所需的測試類裝入。為了確保這一點(diǎn),需要使用<classpath>,使注入指令的測試類位于測試類之前。
- 使用<report>產(chǎn)生覆蓋測試的報(bào)告。
2. 使用例子:
<!-- 采用debug模式編譯被測試類 -->
<javac destdir="${dist.coverage.classes}" deprecation="on" debug="yes">
<src path="${src.code}"/>
<classpath refid="classpath"/>
</javac>
<!-- 編譯被測試類的junit代碼 -->
<javac destdir="${dist.coverage.junit}" deprecation="on">
<src path="${src.junit}"/>
<classpath refid="classpath"/>
</javac>
<!-- 定義jcoverage任務(wù) -->
<path id="jcoverage">
<fileset dir="junit_lib">
<include name="jcoverage.jar"/>
</fileset>
</path>
<taskdef classpathref="jcoverage" resource="tasks.properties"/>
<!-- 給被測試類二進(jìn)制代碼中注入jcoverage的指令 -->
<instrument todir="${dist.coverage.instrument}">
<classpath refid="classpath"/>
<!-- 忽略org.apache.common的應(yīng)用 -->
<ignore regex="org.apache.common.*"/>
<fileset dir="${dist.coverage.classes} ">
<include name="**/*.class"/>
</fileset>
</instrument>
<!-- 啟動junit,進(jìn)行代碼覆蓋測試 -->
<junit printsummary="yes" haltonfailure="no" fork="yes">
<classpath>
<!-- 注意:被注入指令的類,位置在測試類之前。
這樣確保它們早于測試類備加載,使指令起作用。 -->
<pathelement location="${dist.coverage.instrument}"/>
<path refid="classpath"/>
<pathelement location="${dist. coverage.junit}"/>
</classpath>
<formatter type="XML"/>
<batchtest todir="${doc.jcoverageReport}">
<fileset dir="${src.junit}" includes="**/*Test.java" />
</batchtest>
</junit>
<!-- 產(chǎn)生代碼覆蓋測試報(bào)告 -->
<report srcdir="${src.code}" destdir="${doc.jcoverageReport}">
3. jcoverage提供的ant任務(wù)標(biāo)簽有:
- <instrument>,在類的二進(jìn)制文件中注入jcoverage指令。注意:一定是debug模式下編譯的類。
- <report>,產(chǎn)生jcoverage報(bào)告,默認(rèn)格式是HTML。也可以產(chǎn)生XML格式方便應(yīng)用客戶自定義的xslt產(chǎn)生其他格式的報(bào)告。產(chǎn)生XML格式的報(bào)告:
<report srcdir="${src.code}" destdir="${doc.jcoverageReport}" format="xml">
- <merge>,整合多個由jcoverage產(chǎn)生的輸出文件。整個jcoverage實(shí)際的運(yùn)作過程是:首先,jcoverage給測試類注入指令產(chǎn)生新類,被注入指令的類在junit運(yùn)行過程中產(chǎn)生輸出文件(后綴為ser),后根據(jù)輸出文件產(chǎn)生報(bào)告。如果有多個輸出文件,jcoverage提供了<merge>來整合這些文件,后,從整合文件中產(chǎn)生整體報(bào)告。用法:
<merge>
<fileset dir="${basedir}">
<include name="**/jcoverage.ser"/>
</fileset>
</merge>
- <check>,檢查測試是否達(dá)到設(shè)定的標(biāo)準(zhǔn),它可以和<report>配合使用。使用例子:
例1 :
<check branch="95" line="95"/>,意思是分支覆蓋率需要達(dá)到95%,行覆蓋率達(dá)到95%。
例2
<check branch="95" line="95">
<regex pattern="xptoolkit.jcoverage.*" branch="85" line="95"/>
</check>
包名符合xptoolkit.jcoverage.*模式的分支覆蓋率達(dá)到85%,行覆蓋率達(dá)到95%其余的分支覆蓋率需要達(dá)到95%,行覆蓋率達(dá)到95%。
檢查表
在使用jcoverage時需要注意的問題:
- 被jcoverage注入指令的類必須是在debug模式下編譯的類。建議將那些使用debug模式編譯的類的存放與終的產(chǎn)品的目錄分開。
- 使用了<instrument>的類,與源類的目錄也好分開。
- 對于那些使用了AOP(如ASPectJ)技術(shù)的項(xiàng)目,jcoverage不能很好的應(yīng)用到那些已經(jīng)添加了Aspect信息的類。
- 代碼覆蓋工具只是給出了指導(dǎo)性的意見,不要過分依賴和相信它的結(jié)果。