ant中使用cobertura分析測試用例的程式碼覆蓋率

n8765發表於2015-05-05

這次還是配置問題,接上上次關於ant指令碼模板的詳細說明。對於一個完整的專案測試報告,一般來說我們會用JUnit生成的report來分析關於測試用例執行情況,但是,我們怎麼樣保證我們的測試用例的測試質量呢,我們如何知道我們的測試用例到底覆蓋了多少我們的工程程式碼呢。Cobertura就是一個很好的開源免費外掛,他不僅僅支援ant,而且對maven的支援也有很不錯的表現。對於Cobertura對Maven的支援我會在下一個專題中專門闡述(官方提供的Maven plug-in有些小bug,別走開,下一專題告訴你,呵呵呵呵),我這篇文章只針對Cobertura在ant中的使用做一個說明。
 
在上一個關於ant指令碼的專題中,我詳細說明了如何用ant來完成mail→mkzip→report→junit→build→prepare→clean等一系列的工作,為了保證專案中能夠使用Cobertura,我這次對上一個專題的ant模板進行適當的修改:mail→mkzip→coverage-report→cover-test→instrument→report→junit→build→prepare→clean
 
我增加了coverage-report(生成測試報告)、cover-test(進行覆蓋率測試)和instrument(生成打過標籤的二進位制classes)等三個target。同時對mkzip和mail的target也進行了適當的修改,以便能夠把進行覆蓋測試的report進行打包發郵件。
 
首先定義一個頂級 taskdef 元素將 cobertura.jar 檔案限定在當前工作目錄中:
<taskdef classpath="cobertura.jar" resource="tasks.properties" />
 
 
接下來需要定義一個instrument任務,該任務將在已經編譯好的類檔案中新增日誌程式碼-打上標籤。todir 屬性指定將測量類放到什麼地方。fileset 子元素指定測量哪些 .class 檔案
    <target name="instrument" depends="report">
       <cobertura-instrument todir="${instrumented.dir}">
           <fileset dir="${pro.build.path}">
              <include name="**/*.class" />
              <exclude name="**/*Test.class" />
           </fileset>
       </cobertura-instrument>
    </target>
 
 
接下來就可以進行覆蓋測試了,定義一個cover-test任務,該任務依賴於instrument任務。要注意的一點就是被測量的類必須在原始類出現在類路徑中之前出現在類路徑中,而且需要將 Cobertura JAR 檔案新增到類路徑中。
    <target name="cover-test" depends="instrument">
       <mkdir dir="${testreportdir}" />
       <junit dir="./" failureproperty="test.failure" printSummary="yes" fork="true" haltonerror="true">
           <classpath location="cobertura.jar" />
           <classpath location="instrumented" />
           <classpath>
              <fileset dir="lib">
                  <include name="**/*.jar" />
              </fileset>
              <pathelement path="${pro.build.path}" />
              <pathelement path="${pro.build.path}" />
           </classpath>
           <batchtest todir="${pro.build.path}">
              <fileset dir="src/main/test">
                  <include name="**/*Test.java" />
              </fileset>
           </batchtest>
       </junit>
    </target>
 
 
生成測試報告,為了能夠使ant支援cobertura-report,同上個專題說到的一樣,我們需要將Cobertura的相關資原始檔在${ANT_HOME}/lib下放一份(cobertura-report不是ant內建標籤):
    <target name="coverage-report" depends="cover-test">
       <cobertura-report srcdir="src/main/java" destdir="instrumented" />
    </target>

修改打包target
    <target name="mkzip" depends="coverage-report">
       <jar destfile="report/html/test-result${ant.project.name}.zip">
           <fileset dir="report/html">
              <include name="**/*.html" />
              <include name="**/*.css" />
              <include name="**/*.txt" />
           </fileset>
       </jar>
       <jar destfile="report/html/cover-test-result${ant.project.name}.zip">
           <fileset dir="instrumented">
              <include name="**/*.html" />
              <include name="**/*.css" />
              <include name="**/*.txt" />
              <include name="**/*.png" />
              <include name="**/*.js" />
           </fileset>
       </jar>
    </target>
 
 
 
 
修改發郵件target
    <target name="mail" depends="mkzip">
       <mail mailhost="smtp.126.com" mailport="25" subject="The Build Test" user="使用者名稱" password="郵箱密碼">
           <from address="你的發信地址" name="Danlley Wei" />
           <fileset dir="report/html">
              <include name="**/test-result${ant.project.name}.zip" />
              <include name="**/cover-test-result${ant.project.name}.zip" />
           </fileset>
           <to address="收信人地址" name="Danlley Wei" />
           <message>The ${pro.name}--${pro.author} has been tested ! </message>
       </mail>
    </target>
 
 
 
最後執行一下看看結果。
 
本專題完整模板
<?xml version="1.0"?>
<project name="springproj" basedir="." default="mail">
    <!--<property file="build.properties" /> -->
    <property name="pro.name" value="springproj" />
    <property name="pro.author" value="Danlley Wei" />
    <property name="src.dir" value="src/main/java" />
    <property name="pro.web.root" value="war" />
    <property name="pro.web.source" value="${pro.web.root}/WEB-INF" />
    <property name="pro.build.path" value="${pro.web.source}/classes" />
    <property name="user.dir" value="${pro.build.path}" />
    <property name="instrumented.dir" value="instrumented" />
    <taskdef classpathref="master-classpath" resource="tasks.properties" />
    <taskdef classpath="cobertura.jar" resource="tasks.properties" />
    <target name="mail" depends="mkzip">
        <mail mailhost="smtp.126.com" mailport="25" subject="The Build Test" user="郵箱使用者名稱" password="郵箱密碼">
            <from address="發信地址" name="Danlley Wei" />
            <fileset dir="report/html">
                <include name="**/test-result${ant.project.name}.zip" />
                <include name="**/cover-test-result${ant.project.name}.zip" />
            </fileset>
            <to address="收信地址" name="Danlley Wei" />
            <message>The ${pro.name}--${pro.author} has been tested ! </message>
        </mail>
    </target>
    <target name="mkzip" depends="coverage-report">
        <jar destfile="report/html/test-result${ant.project.name}.zip">
            <fileset dir="report/html">
                <include name="**/*.html" />
                <include name="**/*.css" />
                <include name="**/*.txt" />
            </fileset>
        </jar>
        <jar destfile="report/html/cover-test-result${ant.project.name}.zip">
            <fileset dir="instrumented">
                <include name="**/*.html" />
                <include name="**/*.css" />
                <include name="**/*.txt" />
                <include name="**/*.png" />
                <include name="**/*.js" />
            </fileset>
        </jar>
    </target>
    <target name="coverage-report" depends="cover-test">
        <cobertura-report srcdir="src/main/java" destdir="instrumented" />
    </target>
    <target name="cover-test" depends="instrument">
        <mkdir dir="${testreportdir}" />
        <junit dir="./" failureproperty="test.failure" printSummary="yes" fork="true" haltonerror="true">
            <classpath location="cobertura.jar" />
            <classpath location="instrumented" />
            <classpath>
                <fileset dir="lib">
                    <include name="**/*.jar" />
                </fileset>
                <pathelement path="${pro.build.path}" />
                <pathelement path="${pro.build.path}" />
            </classpath>
            <batchtest todir="${pro.build.path}">
                <fileset dir="src/main/test">
                    <include name="**/*Test.java" />
                </fileset>
            </batchtest>
        </junit>
    </target>
    <target name="instrument" depends="report">
        <cobertura-instrument todir="${instrumented.dir}">
            <fileset dir="${pro.build.path}">
                <include name="**/*.class" />
                <exclude name="**/*Test.class" />
            </fileset>
        </cobertura-instrument>
    </target>
    <target name="report" depends="junit">
        <junitreport id="myJUnitReport" taskname="reported" todir="report" description="Junit Report">
            <fileset dir="report">
                <include name="TEST-*.xml" />
            </fileset>
            <report todir="report/html" />
        </junitreport>
    </target>
    <target name="junit" depends="build">
        <mkdir dir="report/html" />
        <junit printsummary="yes" haltonerror="yes" haltonfailure="yes" fork="yes">
            <classpath location="${build.instrumented.dir}" />
            <formatter type="plain" usefile="false" />
            <formatter type="xml" />
            <test name="org.danlley.hibernate.dao.DeptDAOImplTest" todir="report" />
            <classpath refid="master-classpath" />
        </junit>
    </target>
    <target name="build" depends="prepare">
        <javac destdir="${pro.build.path}" target="1.5" debug="true">
            <src path="src/main/java" />
            <classpath refid="master-classpath" />
        </javac>
        <javac destdir="${pro.build.path}" target="1.5">
            <src path="src/main/test" />
            <classpath refid="master-classpath" />
        </javac>
    </target>
    <target name="prepare" depends="clean">
        <copy todir="${pro.build.path}">
            <fileset dir="${src.dir}">
                <include name="**/*.properties" />
                <include name="**/*.xml" />
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete>
            <fileset dir="${pro.build.path}">
                <include name="**/*.*" />
            </fileset>
            <fileset dir="report">
                <include name="**/*.*" />
            </fileset>
            <fileset dir="instrumented">
                <include name="**/*.*" />
            </fileset>
        </delete>
    </target>
    <path id="master-classpath">
        <fileset dir="lib">
            <include name="*.jar" />
        </fileset>
        <pathelement path="${pro.build.path}" />
    </path>
</project>


相關文章