學習Maven之Cobertura Maven Plugin



cobertura-maven-plugin是個什么鬼?

cobertura-maven-plugin是一個校驗單元測試用例覆蓋率的工具,可以生成一個測試覆蓋率報告,可以給單元測試用例編寫提供參考.

helloword

cobertura-maven-plugin的使用也很簡單,首先你要有源碼,然后要有對這個源碼編寫的測試代碼,最后在pom.xml中配置上cobertura-maven-plugin執行一行命令就可以了.

我們先來准備一個源碼和測試用例:

要被測試的代碼

package com.qyf404.learn.maven;

public class App {
    public int add(int a, int b) {
        return a + b;
    }
    public int subtract(int a, int b) {
        return a - b;
    }
}

測試用例代碼

package com.qyf404.learn.maven;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;

public class AppTest {
    private App app;
    @Before
    public void setUp() {
        app = new App();
    }
    @Test
    public void testAdd() throws InterruptedException {
        int a = 1;
        int b = 2;
        int result = app.add(a, b);
        Assert.assertEquals(a + b, result);
    }
    @Test()
    public void testSubtract() throws InterruptedException {
        int a = 1;
        int b = 2;
        int result = app.subtract(a, b);
        Assert.assertEquals(a - b, result);
    }
    @After
    public void tearDown() throws Exception {
    }
}

pom.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.qyf404</groupId>
    <artifactId>learn-maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>cobertura-maven-plugin</artifactId>
                <version>2.7</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

數據都准備好了,我們執行以下maven命令mvn cobertura:cobertura,執行完后會在target目錄里找到site目錄,用瀏覽器打開里面的index.html,這就是測試用例執行完后cobertura-maven-plugin得出的覆蓋率報告.

報告內容如下:

分析后台日志

我們再看看這時后台日志打印的內容

qyfmac$ mvn clean cobertura:cobertura
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building learn-maven 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ learn-maven ---
[INFO] Deleting /Users/qyfmac/git/learn-maven/target
[INFO] 
[INFO] >>> cobertura-maven-plugin:2.7:cobertura (default-cli) > [cobertura]test @ learn-maven >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ learn-maven ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/qyfmac/git/learn-maven/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ learn-maven ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/qyfmac/git/learn-maven/target/classes
[INFO] 
[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ learn-maven ---
[INFO] Cobertura 2.1.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[INFO] Cobertura: Saved information on 1 classes.
[INFO] Cobertura: Saved information on 1 classes.

[INFO] Instrumentation was successful.
[INFO] NOT adding cobertura ser file to attached artifacts list.
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ learn-maven ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/qyfmac/git/learn-maven/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ learn-maven ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/qyfmac/git/learn-maven/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ learn-maven ---
[INFO] Surefire report directory: /Users/qyfmac/git/learn-maven/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.qyf404.learn.maven.AppTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.335 sec
[INFO] Cobertura: Loaded information on 1 classes.
[INFO] Cobertura: Saved information on 1 classes.

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

[INFO] 
[INFO] <<< cobertura-maven-plugin:2.7:cobertura (default-cli) < [cobertura]test @ learn-maven <<<
[INFO] 
[INFO] --- cobertura-maven-plugin:2.7:cobertura (default-cli) @ learn-maven ---
[INFO] Cobertura 2.1.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[INFO] Cobertura: Loaded information on 1 classes.
Report time: 159ms

[INFO] Cobertura Report generation was successful.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.624 s
[INFO] Finished at: 2015-12-08T16:42:47+08:00
[INFO] Final Memory: 22M/227M
[INFO] ------------------------------------------------------------------------

  • 這行日志[INFO] >>> cobertura-maven-plugin:2.7:cobertura (default-cli) > [cobertura]test @ learn-maven >>>告訴我們cobertura-maven-plugin綁定到了maven生命周期test上.

  • 這行日志[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ learn-maven ---告訴我們在完成項目源碼編譯后,執行了cobertura:instrument,對項目源碼做了標記.

  • 這兩行日志

[INFO] Cobertura: Loaded information on 1 classes.
[INFO] Cobertura: Saved information on 1 classes.

```
在執行測試用例時打出的,很明顯`cobertura-maven-plugin`在執行測試用例時做了些事情(這只是個猜測,具體干了啥是要看源碼的).
  • 這行日志[INFO] Cobertura Report generation was successful.告訴我們生成覆蓋率報告成功.而之前執行了測試用例,而且生成報告用了之前生成的class文件.

通過分析日志,我們基本能猜測到:

  1. cobertura-maven-plugin綁定到了maven生命周期test上.
  2. 源碼編譯完成后,cobertura-maven-plugin生成了自己的一套class文件來標記源碼,存放在/target/generated-classes/cobertura/目錄里.
  3. 測試用例執行時,cobertura-maven-plugin修改了自己生成的那套標記源碼的class文件,並根據這套class文件生成了最終的覆蓋率報告.

goals介紹

總體來說cobertura-maven-plugin的使用還是很簡單的.下面我們來看看cobertura-maven-plugin里除了cobertura:cobertura命令還有哪些命令.執行mvn cobertura:help我們會得到該插件的一個幫助文檔.

qyfmac$ mvn cobertura:help
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building learn-maven 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- cobertura-maven-plugin:2.7:help (default-cli) @ learn-maven ---
[INFO] Mojo's Maven plugin for Cobertura 2.7
  This is the Mojo's Maven plugin for Cobertura. Cobertura is a free Java tool
  that calculates the percentage of code accessed by tests. It can be used to
  identify which parts of your Java program are lacking test coverage.

This plugin has 8 goals:

cobertura:check
  Check the coverage percentages for unit tests from the last instrumentation,
  and optionally fail the build if the targets are not met. To fail the build
  you need to set configuration/check/haltOnFailure=true in the plugin's
  configuration.

cobertura:check-integration-test
  Check the coverage percentages for unit tests and integration tests from the
  last instrumentation, and optionally fail the build if the targets are not
  met. To fail the build you need to set configuration/check/haltOnFailure=true
  in the plugin's configuration.

cobertura:clean
  Clean up the files that Cobertura Maven Plugin has created during
  instrumentation.

cobertura:cobertura
  Instrument the compiled classes, run the unit tests and generate a Cobertura
  report.

cobertura:cobertura-integration-test
  Instrument the compiled classes, run the unit tests and integration tests and
  generate a Cobertura report.

cobertura:dump-datafile
  Output the contents of Cobertura's data file to the command line.

cobertura:help
  Display help information on cobertura-maven-plugin.
  Call mvn cobertura:help -Ddetail=true -Dgoal=<goal-name> to display parameter
  details.

cobertura:instrument
  Instrument the compiled classes.


[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.822 s
[INFO] Finished at: 2015-12-03T16:23:59+08:00
[INFO] Final Memory: 8M/156M
[INFO] ------------------------------------------------------------------------

我們逐個介紹一下.

  • cobertura:check

    根據最新的源碼標記(生成的class文件)校驗測試用例的覆蓋率,如果沒有達到要求,則執行失敗.

  • cobertura:check-integration-test

    這個命令和cobertura:check功能是一樣的,區別是二者綁定的maven生命周期不一樣.cobertura:check綁定了test, cobertura:check-integration-test綁定了verify.再說的明白些,maven生命周期中有一個是test跑得單元測試,還有一個是integration-test跑的集成測試.而verify前就是integration-test.即cobertura:check-integration-testcobertura:check涵蓋的測試用例更多.

  • cobertura:clean

    這個好理解,就是清理掉目錄/target/cobertura/中得文件.目前發現里面就一個文件cobertura.ser.

  • cobertura:cobertura

    這個插件的關鍵命令.標記被編譯的文件,運行單元測試,生成測試報告.

  • cobertura:cobertura-integration-test

    cobertura:cobertura做了一樣的事情,區別是包含了集成測試用例.

  • cobertura:dump-datafile

    在命令行輸出覆蓋率數據.數據依據是生成的class文件.這個命令我沒搞懂他的意義何在.在后面一個有趣的實驗我們會用這個命令來更好的理解cobertura-maven-plugin.

  • cobertura:help

    不解釋.

  • cobertura:instrument

    標記被編譯的class文件.執行這個命令會在目錄/target/generated-classes/cobertura下生成一套class文件.

一個有趣的實驗

為了更好的理解cobertura-maven-plugin命令,我們現在做個有趣的實驗,觀察target目錄和控制台下發生了什么.

  • 1.我們執行命令mvn clean先清理掉target中的文件.

  • 2.執行命令mvn compile編譯源文件.

  • 3.執行mvn cobertura:dump-datafile命令,后台日志顯示執行失敗.

[ERROR] Failed to execute goal org.codehaus.mojo:cobertura-maven-plugin:2.7:dump-datafile (default-cli) on project learn-maven: Unable to dump nonexistent dataFile [/Users/qyfmac/git/learn-maven/target/cobertura/cobertura.ser] -> [Help 1]
```

  • 4.執行命令mvn cobertura:instrument標記被編譯的文件.我們會發現多了幾個文件在target目錄里.

  • 5.執行命令mvn cobertura:dump-datafile打印出覆蓋率信息.

    [INFO] --- cobertura-maven-plugin:2.7:dump-datafile (default-cli) @ learn-maven ---
    

[INFO] Cobertura: Loaded information on 1 classes.
[INFO]
[INFO]
[INFO]
[INFO]

```
  • 6.執行命令mvn cobertura:cobertura生成覆蓋率報告.

  • 7.再次執行mvn cobertura:dump-datafile打印出覆蓋率信息.

    [INFO] --- cobertura-maven-plugin:2.7:dump-datafile (default-cli) @ learn-maven ---
    

[INFO] Cobertura: Loaded information on 1 classes.
[INFO]
[INFO]
[INFO]
[INFO]

```

實驗做完了.一共7步,執行了mvn cobertura:cobertura命令3次.

  1. 第一次執行報錯,是因為標記文件沒有生成,沒有找到要解析的文件.
  2. 第二次執行,打印出了日志,但是測試用例還沒執行,所以測試覆蓋率還是初始狀態,多數為0%.
  3. 第三次執行,打印出了日志,顯示了測試覆蓋情況.

校驗規則

一般我們執行cobertura:coberturacobertura:cobertura-integration-test就夠了.但是在做持續集成時,我們可能希望能自動化去檢驗測試用例的覆蓋情況,比如當覆蓋率低於70%時打包失敗.這個時候就用到cobertura:checkcobertura:check-integration-test命令了.

cobertura-maven-plugin允許用戶配置一些規則,來校驗測試覆蓋率.

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>cobertura-maven-plugin</artifactId>
        <version>2.7</version>
        <configuration>
          <check>
            <!--每個類的分支覆蓋率-->
            <branchRate>85</branchRate>
            <!--每個類的代碼行覆蓋率-->
            <lineRate>85</lineRate>
            <!--校驗失敗則中止.即為true時如果校驗失敗則打包執行失敗,反之則只是打出告警日志-->
            <haltOnFailure>true</haltOnFailure>
            <!--整體的分支覆蓋率-->
            <totalBranchRate>85</totalBranchRate>
            <!--整體的代碼行覆蓋率-->
            <totalLineRate>85</totalLineRate>
            <!--每個包的分支行覆蓋率-->
            <packageBranchRate>85</packageBranchRate>
            <!--每個包的代碼行覆蓋率-->
            <packageLineRate>85</packageLineRate>
            <regexes>
              <!--通過表達式設定覆蓋率伐值-->
              <regex>
                <pattern>com.qyf404.learn.*</pattern>
                <branchRate>90</branchRate>
                <lineRate>80</lineRate>
              </regex>
            </regexes>
          </check>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

默認這個校驗是需要單獨敲命令的,當然可以根據實際需要,在execution里配置goalphase來完成命令的綁定.比如在打包前做校驗,可以這么配置execution .

<plugins>
  ...
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>cobertura-maven-plugin</artifactId>
    <version>2.7</version>
    <configuration>
      <check>
      ...
      </check>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>check</goal>
        </goals>
        <phase>prepare-package</phase>
      </execution>
    </executions>
  </plugin>
  ...
</plugins>

統計范圍

有時候我們要做覆蓋率統計時,不需要全部代碼都做的,為了更准確的統計我們想知道的代碼的測試用例覆蓋率,我們就需要加一些配置,來控制統計范圍.

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>cobertura-maven-plugin</artifactId>
  <version>2.7</version>
  <configuration>
    <instrumentation>
      <!-- 這種方式我沒試驗成功.如果有誰配置生效了,請留言告知 http://qyf404.cnblogs.com
      <ignores>
        <ignore>com.example.boringcode.*</ignore>
      </ignores>
      -->
      <!--忽略列表.根據class文件路徑進行匹配-->
      <excludes>
        <exclude>com/qyf404/learn/**/App.class</exclude>
      </excludes>
    </instrumentation>
  </configuration>
</plugin>

報表格式

默認情況下,插件會在target/site下生成html格式的報表.html格式的給人看比較直觀,但是如果報表要導入到其他系統還是xml解析起來簡單.讓我們看看怎么配置吧.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>cobertura-maven-plugin</artifactId>
    <version>2.7</version>

    <configuration>
    	 <!--這個標簽一般不在這配置,一般跟着命令后面作為參數使用-->
        <!--<format>xml</format>-->
        <formats>
            <format>xml</format>
            <format>html</format>
        </formats>
    </configuration>
</plugin>

其實還是簡單的.就是這有兩個同級標簽<format><formats>讓人犯暈.其實也不難,<formats>的配置允許同時輸出多個格式的報表. <format>的作用更多的時作為命令參數傳入,比如mvn clean cobertura:cobertura -Dcobertura.report.format=xml,從這我們也就知道了<format>要比<formats>優先級高.

跳過執行

cobertura-maven-plugin的跳過執行的配置主要由三種:

  1. <configuration>中配置:

    <configuration>
    	<skip>true</skip>
    </configuration>
    
  2. <properties>中配置:

    <properties>
       	<cobertura.skip>true</cobertura.skip>
    </properties>
    
  3. 命令中配置mvn clean cobertura:cobertura -Dcobertura.skip=true.

結語

好了,cobertura-maven-plugin就介紹這么多了,更多cobertura-maven-plugin的使用方法大家可以參閱官方文檔

本文的示例代碼這里可以下到 https://github.com/qyf404/learn-maven/tree/cobertura-maven-plugin.

參考

關於作者


免責聲明!

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



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