在maven 的項目中使用cobertura的插件來生成java代碼覆蓋率的報告,但實際使用中,經常會出現出現報告的值全部 0%,特此文檔來說明如何解決該問題。
所有的出現覆蓋率為0%的問題均與運行單元測試的插件surefire有關,出現的各種問題均是由於該插件的設置forkcount與reuseForks所影響。
如果出現上述問題,請根據以下的說明與要求來配置surefire插件。
surefire插件官方說明: https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html
情況1:cobertura插件的bug引起,當maven-surefire-plugin中的配置項forkconut為0時,第一次產生報告時就會導致報告為0.
bug url: http://jira.codehaus.org/browse/MCOBERTURA-70
解決方案:
1. 運行兩次 mvn cobertura:cobertura命令, 在jenkins中就是配置運行兩次該命令。
2. 設置forkcount = 1, 修改參照:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>x.x.x</version>
<configuration>
<forkCount>1</forkCount>
<reuseForks>true</reuseForks>
</configuration>
</plugin>
PS:
1.此為默認配置,直接從adq-parent或直接使用該插件就為該值。
2.另外關於forkcount>0 設置可能導致單元測試運行在多個線程上而導致不是順序執行的問題,我查詢了官網的說明,原文為:
The default setting is forkCount=1/reuseForks=true, which means that Surefire creates one new JVM process to execute all tests in one maven module.
所以,如果項目中只有一個模塊的話,所有的測試應該運行在同一個線程中的,所以設置為1也是可以的。
情況2: 當單元測試用例的內容較多或引用較多的外部lib,就可能會引起插件cobertura運行時出現內存溢出的錯誤(在日志中會有java.lang.OutOfMemoryError錯誤),而導致寫代碼覆蓋率數據失敗。Edit解決方案:首先需要說明該種情況在日志中會有OOM的錯誤。
1. 修改reuseForks = false, 注意此時surefire會為每個測試類啟動一個獨立JVM來運行單元測試,雖然避免了問題,但是如果單元測試之間有依賴關系的話就不能這樣解決。另外這樣也會導致運行測試的時間大大增加, 修改參照:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>x.x.x</version>
<configuration>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
2. 如果第一種解決方法不適用的話,可以使用此種方法,為啟動的JVM增加啟動參數,-Xms512m -Xmx1024m -XX:MaxPermSize=128m, 設置啟動內存同樣能解決。注意在JDK1.8中,MaxPermSize已經被刪除,並且引入了一種新的機制,應該不會再出現此類問題,所以如果修改了該值,JDK升級至1.8后請刪除, 以下為修改的參照:
<groupid>org.apache.maven.plugins</groupId>
<artifactid>maven-surefire-plugin</artifactId>
<version>版本看情況吧~</version>
<configuration>
<argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=128m</argLine>
</configuration>
