我們都知道 Spock 是一個單測框架,其特點是語法簡明。但當我們使用 Spock 寫了一堆單元測試之後,如何生成對應的單測覆蓋率報告呢?一般來說,我們會使用兩個插件來一起完成單測覆蓋率報告的生成,分別是:
- Maven Surefire Plugin
- JaCoCo Plugin
其中 Maven Surefire Plugin 是用來在 Maven 的編譯階段運行單測代碼,而 JaCoCo 則是用來生成具體的單測覆蓋率報告。本文將新建一個非 Web 項目來演示如何生成 Spock 的單測覆蓋率報告。
初始化項目
這裏初始化項目一個普通的 Java 項目,並引入對應的 Spock 依賴,如下代碼所示:
<!-- spock 依賴-->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>2.0-M2-groovy-3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
接着寫一個計算器類,用於演示單測覆蓋率,如下代碼所示:
package tech.shuyi;
public class AdvancedCalculator {
Integer add(int a, int b) {
return a + b;
}
Integer subtract(int a, int b) {
return a - b;
}
Integer multi(int a, int b) {
return a * b;
}
Integer divide(int a, int b) {
return a / b;
}
}
接着在 test.groovy.tech.shuyi
目錄寫一個 Groovy 單測,如下代碼所示:
package tech.shuyi
import spock.lang.Specification
class AdvancedCalculatorTest extends Specification {
def calendar = new AdvancedCalculator()
def "Add"() {
expect: calendar.add(1, 2) == 3
}
def "Substract"() {
expect: calendar.subtract(2, 1) == 1
}
def "Multi"() {
expect: calendar.multi(2, 3) == 6
}
def "Divide"() {
expect: calendar.divide(16, 4) == 4
}
}
接着我們嘗試運行一下單測文件,如無異常應該是成功的。
引入插件
在這裏,我們要引入對應的兩個插件,並做一些簡單地配置。
首先,在 pom.xml
文件引入 Surefire 插件配置,如下代碼所示:
<!-- surefire plugin with spock and junit -->
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.9.0</version>
<executions>
<execution>
<goals>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<!-- 配置單測失敗幾次後停止執行 -->
<skipAfterFailureCount>0</skipAfterFailureCount>
<!-- 不允許跳過單測 -->
<skipTests>false</skipTests>
</configuration>
</plugin>
接着引入 JaCoCo Plugin 的配置,如下代碼所示:
<!-- JaCoCo plugin -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<configuration>
<includes>
<include>tech/**/*</include>
</includes>
</configuration>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
生成報告
做好上述報告後,直接執行 mvn test
就可以生成單測覆蓋率報告了。如果沒有什麼異常的話,程序會生成單測覆蓋率報告文件,地址爲: target/site/jacoco/index.html
。
我們使用瀏覽器打開該文件可以瀏覽到單測覆蓋率情況,如下圖所示:
疑問
關於如何配置這兩個插件的資料很多,但都運行不起來。後面我參考了官網的配置,就成功配置好了。
- Surefire Plugin 官網文檔:Maven Surefire Plugin – Introduction
- JaCoCo Plugin 官網文檔:JaCoCo - Maven Plug-in
但對於這兩個插件,我還是有一定疑問的,例如:
- 這兩個插件到底都是啥作用?
- 是否一定要搭配一起使用?
通過 Surefire 插件官網,我們可以大概知道其作用爲:在編譯的 test 階段,用於執行程序的單元測試,最終生成 txt
和 xml
格式的報告,存放地址爲 ${basedir}/target/surefire-reports/TEST-*.xml
。
由此可見,Surefire 的主要作用還是用於執行程序的單測程序,而不是生成報告。當然,官網文檔也說了,你可以使用 Maven Surefire Report Plugin
來生成 HTML 格式的報告。我根據這個文檔(Maven Surefire Report Plugin – Usage)配置了一下 surefire-report 插件,成功地生成 HTML 格式的報告,如下圖所示。
可以看到 surefire-report 插件生成的 HTML 報告還是比較簡陋的,跟 JaCoCo 插件生成的相比,顯然後者更加可視化一些。
看到這裏,我相信大家應該能弄明白前面兩個問題了:
- 這兩個插件到底都是啥作用?
- 是否一定要搭配一起使用?
簡單地說,Surefire 插件主要是運行單測,生成單測數據。對於 JaCoCo 插件而言,其作用是基於 Surefire 插件去生成可視化的報告。JaCoCo 插件需要基於 Surefire 插件使用,如果去掉 Surefire 插件,JaCoCo 就生成不了報告了。