maven外掛之maven之maven-surefire-plugin
1.maven-surefire-plugin是個什麼鬼?
如果你執行過 mvn test
或者執行其他maven命令時跑了測試用例,你就已經用過 maven-surefire-plugin
了。 maven-surefire-plugin
是maven裡執行測試用例的外掛,不顯示配置就會用預設配置。這個外掛的 surefire:test
命令會預設繫結maven執行的 test
階段。
maven的生命週期有哪些階段?
[validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test
2.maven-surefire-plugin的使用
如果說maven意見有了maven-surefire-plugin的預設配置,我們還有必要了解maven-surefire-plugin的配置麼?答案是肯定的。雖說maven-surefire-plugin有預設配置,但是當需要修改一些測試執行的策略時,就有必要我們去重新配置這個外掛了。
2.1.配置JUnit
2.1.1.外掛自動匹配
最簡單的配置方式就不配置或者是隻宣告外掛。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
</plugin>
這個時候maven-surefire-plugin會按照如下邏輯去尋找JUnit的版本並執行測試用例。
if the JUnit version in the project >= 4.7 and the parallel attribute has ANY value
use junit47 provider
if JUnit >= 4.0 is present
use junit4 provider
else
use junit3.8.1
2.1.2.外掛手動匹配
當然,如果你明確用的是JUnit4.7及以上版本,可以明確宣告:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
</plugin>
JUnit4.0(含)到JUnit4.7(不含)的版本,這樣宣告:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit4</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
</plugin>
JUnit3.8(含)到JUnit4.0(不含)的版本,這樣宣告:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit3</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
</plugin>
JUnit3.8以下的版本surefire不支援。建議大家用最新的JUnit版本,目前是4.12.
<dependencies>
[...]
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
本文的例子我們用的Junit4.12.
2.2.準備測試用例
我們現在準備兩個類,一個被測試的類,一個測試用例.目錄結構如下
現在我們準備一個簡單的類.
package com.qyf404.learn.maven;
public class App {
publicintadd(int a, int b) {
return a + b;
}
publicintsubtract(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;
public class AppTest {
private App app;
@Before
publicvoidsetUp() {
app = new App();
}
@Test
publicvoidtestAdd() throws InterruptedException {
int a = 1;
int b = 2;
int result = app.add(a, b);
Assert.assertEquals(a + b, result);
}
@Test
publicvoidtestSubtract() throws InterruptedException {
int a = 1;
int b = 2;
int result = app.subtract(a, b);
Assert.assertEquals(a - b, result);
}
@After
publicvoidtearDown() throws Exception {
}
}
2.3.用maven執行測試用例
用maven執行測試用例很簡單,直接執行 mvn test
就可以.一般我們執行maven打包命令 mvn
package
前maven會預設執行 test
命令.
qyfmac$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building learn-maven 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[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] --- 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 2 source files to /Users/qyfmac/git/learn-maven/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.19:test (default-test) @ learn-maven ---
[WARNING] The parameter forkMode is deprecated since version 2.14. Use forkCount and reuseForks instead.
[INFO] Surefire report directory: /Users/qyfmac/git/learn-maven/target/surefire-reports
[INFO] Using configured provider org.apache.maven.surefire.junit4.JUnit4Provider
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.qyf404.learn.maven.AppTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.003 sec - in com.qyf404.learn.maven.AppTest
Results :
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.622 s
[INFO] Finished at: 2015-12-01T11:36:04+08:00
[INFO] Final Memory: 14M/228M
[INFO] ------------------------------------------------------------------------
qyfmac$
其實我們會發現關鍵內容還是JUnit的東西,maven只是作為一個呼叫器呼叫了一下這些測試用例.
3.進階
後面讓我們來研究一下 maven-surefire-plugin
這個外掛更多的知識,這些多數都是和配置相關的.
3.1.跳過測試用例
在工作中,很多情況下我們打包是不想執行測試用例的,可能是測試用例不完事,或是測試用例會影響資料庫資料.跳過測試用例執行過程有三個種方法.
3.1.1.在configuration中宣告
在外掛的configuration配置中宣告跳過測試用例
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
3.1.2.在properties中宣告
在properties配置中宣告跳過測試用例
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
或
<properties>
<skipTests>true</skipTests>
</properties>
3.1.3.在執行命令中宣告
在執行maven命令時可以宣告跳過測試用例
qyfmac$ mvn test -Dmaven.test.skip=true
或
qyfmac$ mvn test -DskipTests=true
3.1.4.跳過測試用例優先順序排序
首先分兩種情況,一種是配置 skipTests
,一種是配置 maven.test.skip
(真要命,宣告位置就三處了,還搞出兩個變數名,一共就是5中情況).
- 如果是配置
skipTests
, configuration的配置優先順序最高,命令中得配置次之, properties的配置最低. -
即
configuration > 命令 > properties
-
如果是配置
maven.test.skip
,命令中得配置優先順序最高, properties的配置最低.即
命令 > properties
-
skipTests
和maven.test.skip
有一個被設定成了true,則跳過測試用例.即
skipTests||maven.test.skip
決定是否跳過測試用例執行.
3.2.maven命令執行一個測試用例
很多情況下我們寫完一個測試用例後,想馬上執行一下,看看執行情況.如果用IDE開發,裡面一般都有直接執行一個測試用例的方法.但是如果用maven命令達到同樣的效果,就需要加些命令引數了.
比如我們現在再加一個測試用例App2Test.java.
package com.qyf404.learn.maven;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class App2Test {
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);
Thread.currentThread().sleep(1000);
Assert.assertEquals(a + b, result);
}
@After
public void tearDown() throws Exception {
}
}
直接執行 mvn test是這樣的,它執行了全部測試用例.
qyfmac$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building learn-maven 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.qyf404.learn.maven.App2Test
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.004 sec - in com.qyf404.learn.maven.App2Test
Running com.qyf404.learn.maven.AppTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec - in com.qyf404.learn.maven.AppTest
Results :
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.773 s
[INFO] Finished at: 2015-12-01T14:57:00+08:00
[INFO] Final Memory: 9M/156M
[INFO] ------------------------------------------------------------------------
現在我們用命令 mvn test -Dtest=App2Test
指定執行App2Test.
qyfmac$ mvn test -Dtest=App2Test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building learn-maven 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.qyf404.learn.maven.App2Test
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.003 sec - in com.qyf404.learn.maven.App2Test
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.061 s
[INFO] Finished at: 2015-12-01T14:58:59+08:00
[INFO] Final Memory: 9M/156M
[INFO] ------------------------------------------------------------------------
-Dtest
的引數是可以用表示式的.
-
比如執行多個測試用例可以用逗號分開
mvn test -Dtest=App2Test,AppTest
. -
也可以用ant風格的路徑表示式
mvn test -Dtest=*2Test
,mvn test -Dtest=???2Test
. -
甚至指定具體的測試方法
mvn test -Dtest=*Test#testAdd
. -
指定具體包裡的測試用例
mvn test -Dtest=com/qyf404/learn/maven/*
.
3.3.測試用例的包含與例外配置
上面說了,在執行命令時可以指定執行哪個或哪些測試用例,其實在pom.xml裡也是可以配置的.比如打包時執行測試用例AppTest,不執行App2Test,可以這麼配置.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47