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文件.
通過分析日志,我們基本能猜測到:
cobertura-maven-plugin
綁定到了maven生命周期test
上.- 源碼編譯完成后,
cobertura-maven-plugin
生成了自己的一套class文件來標記源碼,存放在/target/generated-classes/cobertura/
目錄里. - 測試用例執行時,
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] ------------------------------------------------------------------------
我們逐個介紹一下.
-
根據最新的源碼標記(生成的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-test
比cobertura:check
涵蓋的測試用例更多. -
這個好理解,就是清理掉目錄
/target/cobertura/
中得文件.目前發現里面就一個文件cobertura.ser
. -
這個插件的關鍵命令.標記被編譯的文件,運行單元測試,生成測試報告.
-
cobertura:cobertura-integration-test
和
cobertura:cobertura
做了一樣的事情,區別是包含了集成測試用例. -
在命令行輸出覆蓋率數據.數據依據是生成的class文件.這個命令我沒搞懂他的意義何在.在后面
一個有趣的實驗
我們會用這個命令來更好的理解cobertura-maven-plugin
. -
不解釋.
-
標記被編譯的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次.
- 第一次執行報錯,是因為標記文件沒有生成,沒有找到要解析的文件.
- 第二次執行,打印出了日志,但是測試用例還沒執行,所以測試覆蓋率還是初始狀態,多數為0%.
- 第三次執行,打印出了日志,顯示了測試覆蓋情況.
校驗規則
一般我們執行cobertura:cobertura
或cobertura:cobertura-integration-test
就夠了.但是在做持續集成時,我們可能希望能自動化去檢驗測試用例的覆蓋情況,比如當覆蓋率低於70%時打包失敗.這個時候就用到cobertura:check
和cobertura: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
里配置goal
和phase
來完成命令的綁定.比如在打包前做校驗,可以這么配置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
的跳過執行的配置主要由三種:
-
<configuration>
中配置:<configuration> <skip>true</skip> </configuration>
-
<properties>
中配置:<properties> <cobertura.skip>true</cobertura.skip> </properties>
-
命令中配置
mvn clean cobertura:cobertura -Dcobertura.skip=true
.
結語
好了,cobertura-maven-plugin
就介紹這么多了,更多cobertura-maven-plugin
的使用方法大家可以參閱官方文檔
本文的示例代碼這里可以下到 https://github.com/qyf404/learn-maven/tree/cobertura-maven-plugin.