Jenkins單元測試


一.簡介

每種編程語言都有自己的單元測試框架。執行單元測試的工作一般由構建工具來完成。Jenk-ins做的只不過是執行這些構建工具的單元測試命令,然后對測試報告進行收集,並呈現。

Jenkins並不會自動幫我們寫單元測試,寫單元測試還是要靠人。為什么要這樣說呢?因為筆者發現,不少人認為Jenkins的自動化測試是指Jenkins代替人自動寫測試。

二.單元測試

JUnit

JUnit是一個Java語言的單元測試框架,由Kent Beck和ErichGamma創建。當執行maven test命令時,Maven會執行測試階段(包括單元測試),然后生成測試報告。

收集並展示JUnit測試報告的步驟如下:
1.安裝Jenkins JUnit插件,搜junit

2.在Jenkins中加入junit步驟,通常將步驟放在post always中,因為當測試不通過時,我們依然可以收集到測試報告

post {
    always {
        junit testResults: "**/target/surefire-reports/*.xml"
    }
}

當pipeline運行結束后,在構建頁的左邊菜單欄及右邊詳情下都會多出一個鏈接:Test Result
file

3.單機“Test Result”進入,可以看到測試報告的詳細信息
file

junit步驟的testResults參數支持Ant風格路徑表達式。**/targetlsurefire-reports/*.xml表示只要是target/surefire-reports目錄下的XML文件就會被當作JUnit測試報告處理,而不論target在哪個層級的目錄下。

JacoCo

JUnit只是方便我們寫單元測試的一個框架,但是並沒有告訴我們有多少代碼被測試覆蓋到了。而JaCoCo填補了這一空白。JaCoCo是一個免費的Java代碼覆蓋率的庫,能幫助我們檢測出代碼覆蓋率,並輸出覆蓋率報告。

JaCoCo提供了以下幾個維度的覆蓋率分析。

  • 指令覆蓋率( Instruction Coverage )
  • 分支覆蓋率( Branch Coverage )
  • 圈復雜度覆蓋率( Cyclomatic Complexity Coverage )
  • 行覆蓋率( Line Coverage )
  • 方法覆蓋率( Method Coverage )
  • 類覆蓋率( Class Coverage )

以下是JaCoCo插件的使用步驟。
1.安裝JaCoCo插件,搜索jacoco

2.在Maven項目中引入JaCoCo插件,執行maven jacoco生成代碼覆蓋率報告

<plugin>
    <groupId>org. jacoco</ groupId>
    <artifactId>jacoco- maven- plugin</ artifactId>
    <version>0.8.2</version>
    <executions>
        <execution>
            <id>prepare- agent</id>
            <goals>
                <goal>prepare - agent</ goal>
            </goals>
        </execution>
        <execution>
            < id>report</id>
            <phase>prepare - package</ phase>
            <goals>
                <goal>report</ goal>
            </goals>
        </execution>
        <execution>
            <id>post- unit - test</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
            <configuration>
                <!-- jacoco執行數據的文件路徑- - >
                <dataFile>target/jacoco. exec</dataFile>
                <!--輸出報告的路徑-- >
                <outputDirectory>target/jacoco- ut</outputDirectory>
            </configuration>

        </execution>
    </executions>
    <configuration>
        <systemPropertyVariables>
            <jacoco- agent . destfile>target/jacoco. exec</jacoco- agent . destfile>
        </ systemPropertyVariables>
    </configuration>
</p1ugin>

3.使用jacoco步驟,在mvn命令之后執行,寫法如下

steps{
    sh "mvn clean install”
    jacoco(
        //代碼覆蓋率統計文件位置,Ant風格路徑表達式
        execPattern: ' target/**/* . exec', 

        // classes 文件位置,Ant風格路徑表達式
        classPattern: ' target/classes',

        //源碼文件位置,Ant風格路徑表達式
        sourcePattern: ' src/main/java',

        //排除分析的位置,Ant風格路徑表達式
        exclus ionPattern: 'src/test*',

        //是否禁用每行覆蓋率的源文件顯示
        skipCopyOfSrcFiles: false,

        //如果為true,則對各維度的覆蓋率進行比較。如果任何一個維度的當前覆蓋率小於最小覆蓋率閾值,則構建狀態為失敗
        //如果當前覆蓋率在最大閾值和最小閾值之間,則當前構建狀態為不穩定;如果當前覆蓋率大於最大閾值,則構建成功
        changeBuildStatus: true,

        //字節碼指令覆蓋率
        minimumInstructionCoverage: ' 30' , maximumInstructionCoverage: '70',

        //行覆蓋率
        minimumLineCoverage: ' 30' ,maximumL ineCoverage: '70',

        //圈復雜度覆蓋率
        minimumComplexityCoverage: ' 30' ,maximumComplexityCoverage:'70', 

        //方法覆蓋率
        minimumMethodCoverage: ' 30' , maximumMethodCoverage:'70',

        //類覆蓋率
        minimumClassCoverage: ' 30',maximumClassCoverage: ' 70',

        //分支覆蓋率
        minimumBranchCoverage: ' 30' ,maximumBranchCoverage:'70',

        //如果為true,則只有所有維度的覆蓋率變化量的絕對值小於相應的變化量閾值時,構建結果才為成功
        build0verBuild: true,
        
        //以下是各個維度覆蓋率的變化量閾值
        deltaInstructionCoverage: ' 80',deltaLineCoverage: '80',
        deltaMethodCoverage: ' 80 ' ,deltaClassCoverage: '80',
        deltaComplexityCoverage: ' 80',deltaBranchCoverage: '80 '
    )
}

為了更好地理解jacoco步驟的參數,我們看看插件在自由風格項目中的UI
file

pipeline運行完成后,我們可以在任務詳情頁的下方看到報告。
file

buildOverBuild和changeBuildStatus參數都能影響Jenkins任務的結果狀態,那么當這兩個參數的值都為true時,結果由其共同決定

* Success AND Success = Success
* Unstable AND Unstable = Unstable
Failure AND Failure = Failure
X AND Failure = Failure, Failure AND X = Failure, X = Success/Unstable/Failure
* Y AND Unstable = Unstable, Unstable AND Y = Unstable, Y = Success/Unstable

最后,各個維度的覆蓋率應該設置多少呢?沒有標准答案。筆者的經驗是先要確定項目是遺留的還是新建的。遺留的就以當前覆蓋率為基線,新建的則設置相對高一些的要求。 再看項目的緊急程度,如果非常緊急的話,則可以考慮放低要求。最后看項目的重要程度,如果這個項目在整個架構中起着非常重要的作用,那么覆蓋率要求會高一些。

三.總結

代碼覆蓋率越高,軟件的質 量就越高嗎?

我們來看看《軟件之道:軟件開發爭議問題剖析》中是怎么說的:為了找到兩者之間的關系,把WindowsVista(4000多萬行代碼、幾千個二進制文件、數千名工程師)的分支覆蓋率( Branch Coverage )與塊覆蓋率( Block Coverage )和其發布六個月內的現場缺陷對應起來。我們觀察到覆蓋率和質量之間有弱正相關性,預測查准率和查全率較差(查准率為83.8% ,查全率為54.8% )。

書中最終給出的答案是:代碼覆蓋率最好不要單獨使用,而是需要與其他指標,如代碼變動率、復雜度等一並考慮。所以,如果考慮將代碼覆蓋率作為團隊開發人員的KPI,請慎重。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM