博客分類:
Maven與測試
Maven 的主要職責之一就是自動運行單元測試,通過 maven-surefire-plugin 與主
流的單元測試框架 Junit3、Junit4、TestNG 集成,並能夠自動生成豐富的結果報告。
1. maven-surefire-plugin 簡介
Maven 本身並不是一個單元測試框架,Maven 只是在構建執行到特定生命週期階
段的時候,通過插件來執行 Junit 或者 TestNG 的測試用例,這個插件稱之爲測試運行
器(Test Runner),也就是 maven-surefire-plugin。
a) 階段綁定
生命週期階段,需要綁定到某個插件的目標才能完成真正的工作,test 階段正是與
maven-surefire-plugin 的 test 目標綁定了,這是一個內置綁定。
b) 測試指令
mvn test
c) 測試源碼路徑
默認 src/test/java。
d) 測試類的命名模式(Junit 爲例)
i. **/Test*.java
任何子目錄下所有命名以 Test 開頭的 Java 類。
ii. **/*Test.java
任何子目錄下所有命名以 Test 結尾的 Java 類。
iii. **/*TestCase.java
任何子目錄下所有命名以 TestCase 結尾的 Java 類。
iv. 例外
以 Tests 結尾的測試類不會得以自動執行。
2. 跳過測試
在日常開發總會遇到跳過測試這種情況,不管是由於有信心沒有錯誤,還是由於測
試時間過於耗時,都不推薦這樣做,更好的做法是優化測試。
a) 跳過測試(不推薦)
i. 命令行
加入參數 skipTests 就可以了,例如:
- mvn package –DskipTests
mvn package –DskipTests
ii. pom.xml
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.5</version>
- <configuration>
- <skipTests>true</skipTests>
- </configuration>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
b) 臨時跳過測試(不推薦)
i. 命令行
- mvn package –Dmaven.test.skip = true
mvn package –Dmaven.test.skip = true
1) maven.test.skip
這個參數控制了maven-compiler-plugin和maven-surefire-plugin 兩
個插件的行爲,測試代碼編譯跳過了,測試運行也跳過了。
ii. pom.xml
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.1</version>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.5</version>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
c) 注意事項
maven-compiler-plugin的testCompile目標和maven-surefire-plugin的
test 目標都提供了一個參數 skip 用來跳過測試編譯和測試運行,而這個參數對應的
命令行表達式爲 maven.test.skip。
3. 動態指定運行測試用例
如果僅僅爲了一個失敗的測試用例而反覆運行所有測試,未免太浪費時間了,當項
目中測試的數目比較大的時候,這種浪費尤其明顯。
a) test 參數
maven-surefire-plugin 提供了一個 test 參數讓 Maven 用戶能夠在命令行指定要
運行的測試用例。
i. 測試用例類名
- mvn test –Dtest = RandomGeneratorTest
mvn test –Dtest = RandomGeneratorTest
只有 RandomGeneratorTest 這一個測試類得到運行。
ii. 星號匹配符
- mvn test –Dtest = Random*Test
mvn test –Dtest = Random*Test
匹配多個測試類,只要滿足以 Random 開頭,以 Test 結尾。
iii. 逗號指定多個測試用例
- mvn test –Dtest = RandomGeneratorTest,AccountCaptchaTest
mvn test –Dtest = RandomGeneratorTest,AccountCaptchaTest
匹配這兩個測試類,多個之間用逗號隔開。
iv. 結合使用星號和逗號
- mvn test –Dtest = Random*Test, AccountCaptchaTest
mvn test –Dtest = Random*Test, AccountCaptchaTest
v. 找不到匹配類
- mvn test –Dtest
mvn test –Dtest
這樣的命令會導致構建失敗,但是可以告訴 maven-surefire-plugin 即使沒有任何測試也不要報錯。
- mvn test –Dtest –DfailIfNoTests = false
mvn test –Dtest –DfailIfNoTests = false
實際上這是另外一種跳過測試的方法。
4. 包含與排除測試用例
maven-surefire-plugin 還是允許用戶通過額外的配置來自定義包含一些其他測
試類,或者排除一些符合默認命名模式的測試類。
a) 包含
由於歷史原因,有些項目所有測試類的名稱都是以 Tests 結尾,這樣的名字不符合默
認的 3 種模式,因此不會被自動運行,但可以這樣配置。
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.5</version>
- <configuration>
- <includes>
- <include>**/*Tests.java</include>
- </includes>
- </configuration>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<includes>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>
i. **
前面的 2 個*用來匹配任意路徑。
ii. *
匹配任意字符。
b) 排除
類似可以使用 excludes 元素排除一些符合默認命名模式的測試類。
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.5</version>
- <configuration>
- <excludes>
- <exclude>**/*ServiceTest.java</exclude>
- <exclude>**/DaoTest.java</exclude>
- </excludes>
- </configuration>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<excludes>
<exclude>**/*ServiceTest.java</exclude>
<exclude>**/DaoTest.java</exclude>
</excludes>
</configuration>
</plugin>
i. 排除以 ServiceTest 結尾的測試類
ii. 排除 DaoTest 的測試類
iii. 有了 excludes 配置後,maven-surefire-plugin 將不再自動運行他們
雖然他們都符合命名模式**/*Test.java。
5. 測試報告
除了命令行輸出,Maven 用戶可以使用 maven-surefire-plugin 等插件以文件的
形式生成更豐富的測試報告。
a) 測試術語(基於 Junit)
i. Failures
失敗,表示要測試的結果與期望值不一致。
ii. Errors
錯誤,表示測試代碼活產品代碼發生了未預期的錯誤。
iii. Skipped
表示那些被標記爲忽略的測試方法。
b) 基本的測試報告
一般情況下,maven-surefire-plugin 會在項目的 target/surefire-reports 目錄
下生成兩種格式的錯誤報告。
i. 簡單文本格式
例如:org.lichee.core.AppTest.txt
ii. 與 Junit 兼容的 XML 格式
XML 格式的測試報告主要是爲了支持工具的解析,如 eclipse 的 Junit 插件可以直接打開這樣的報告。
例如:TEST-org.lichee.core.AppTest.xml
1) 報告標準
由於這種 XML 格式已經成爲了 Java 單元測試報告的事實標準,一些其他
工具也能使用他們。如:持續繼承服務器 Hudson 就能使用這樣的文件提
供持續繼承的測試報告。
c) 測試覆蓋率報告
測試覆蓋率是衡量項目代碼質量的一個重要的參考指標,Cobertura 是一個優
秀的開源測試覆蓋率統計工具,Maven 通過 cobertura-maven-plugin 與之集成,
就可以使用簡單的命令爲 Maven 項目生成測試覆蓋率報告。
i. pom.xml
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <version>2.6</version>
- </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
</plugin>
ii. 指令
- mvn cobertura:cobertura
mvn cobertura:cobertura
iii. 查看報告
打開 target/site/cobertura 下的 index.html 文件。
1) 全部類的測試覆蓋報告
2) 具體某個類的測試覆蓋報告
6. 重用測試代碼
默認的打包行爲是不會包含測試代碼的,因此在使用外部依賴的時候,其構件一般
都不會包含測試代碼。但這個需求又是很常見的,可能存在高質量的測試基類、或者是
一些常見的測試工具類。
a) maven-jar-plugin
這個插件可以將測試類打包。
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
i. jar 目標
生成構件的 jar 包,綁定在 default 生命週期的 package 階段。
例如:lichee-core-1.0.0.jar。
ii. test-jar 目標
生成構件的測試 jar 包,默認綁定聲明週期階段爲 package。
例如:lichee-core-1.0.0-tests.jar。
1) 引用
所有的測試包構件都使用特殊的 test-jar 打包類型。
- <dependency>
- <groupId>org.lichee</groupId>
- <artifactId>lichee-core</artifactId>
- <version>1.0.0</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>