Maven經過Maven Surefire Plugin插件執行單元測試。(經過Maven Failsafe Plugin插件執行集成測試)html
在pom.xml中配置JUnit,TestNG測試框架的依賴,便可自動識別和運行src/test目錄下利用該框架編寫的測試用例。surefire也能識別和執行符合必定命名約定的普通類中的測試方法(POJO測試)。java
生命週期中test階段默認綁定的插件目標就是surefire中的test目標,無需額外配置,直接運行mvn test就能夠。正則表達式
基本配置以下,下文中的配置項如無特殊說明,都位於pom文件的<configuration>節點中。apache
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.18.1</version> <configuration> ......
配置內容
...... </configuration> </plugin>
<skipTests>true</skipTests>
或者 併發
mvn install -DskipTests
或者 (Compliler插件也會根據該參數跳過編譯測試類) app
mvn install -Dmaven.test.skip=true
Maven在測試階段出現失敗的用例時,默認的行爲是中止當前構建,構建過程也會以失敗結束。有時候(如測試驅動開發模式)即便測試出現失敗用例,仍然但願能繼續構建項目。框架
<testFailureIgnore>true</testFailureIgnore>
或者socket
mvn test -Dmaven.test.failure.ignore=true
surefire默認的查找測試類的模式以下:maven
自定義包含和排除模式,支持ant-style表達式和 正則表達式(%regex[...], 按.class文件匹配而不是.java)ide
<includes> <include>Sample.java</include> <include>%regex[.*[Cat|Dog].*Test.*]</include> </includes>
<excludes> <exclude>**/TestCircle.java</exclude> <exclude>**/TestSquare.java</exclude> </excludes>
指定測試類
mvn -Dtest=TestClassName test mvn -Dtest=TestCi*le test mvn -Dtest=TestSquare,TestCi*le test
指定單個測試類中的多個方法(Junit4+, TestNG)
mvn -Dtest=TestCircle#mytest test mvn -Dtest=TestCircle#test* test mvn -Dtest=TestCircle#testOne+testTwo test #(Surefire2.12.1+, Junit4.x+)
(mvn命令加-T選項,多模塊項目的各個模塊能夠並行構建。)
兩個方式:
方法一是使用parallel 參數,在一個進程中執行多個線程。
Junit4.7+可用值有:methods, classes, both(classesAndMethods), suites, suitesAndClasses, suitesAndMethods, classAndMethods, all。Junit Runner必須繼承自orig.junit.runners.ParentRunner或爲指定@org.junit.runner.RunWith。
線程數配置:useUnlimitedThreads 爲true,不限制線程數。useUnlimitedThreads 爲false時可使用threadCount和perCoreThreadCount參數。還能夠經過threadCountSuites,threadCountClasses,threadCountMethods在不一樣粒度限制線程。parallelTestsTimeoutInSeconds和parallelTestsTimeoutForcedInSeconds參數設置線程的超時時間。Junit中@NotThreadSafe註解的內容會單線程執行,避免併發。
方法二是使用forkCount參數,建立多個測試進程。
若是forkCount參數值後加C,表示乘以CPU核數(如forkCount=2.5C)。reuseForks表示一個測試進程執行完了以後是殺掉仍是重用來繼續執行後續的測試。 默認配置爲forkCount=1/reuseForks=true。進程的測試單元是class,逐個class的傳遞給測試進程。
能夠用systemPropertyVariables 傳入系統參數(mvn test -D...或配置元素),也可使用argLine傳入JVM選項。argLine或者systemPropertyVariables配置裏中也能用${surefire.forkNumber}佔位符,表明每一個進程本身的fork編號(1...n),用來向每一個進程傳入獨立的資源配置(forkCount=0時,該佔位符值爲1)。
若是使用-T n同時執行多個mvn模塊,每一個模塊都會有forkCount個進程,${surefire.forkNumber}的值爲1..n*forkCount。
surefire2.14以前的版本使用forkMode進行配置,對應關係以下。
Old Setting | New Setting |
forkMode=once (default) | forkCount=1 (default), reuseForks=true (default) |
forkMode=always | forkCount=1 (default), reuseForks=false |
forkMode=never | forkCount=0 |
forkMode=perthread, threadCount=N | forkCount=N, (reuseForks=false, if you did not had that one set) |
多種並行方式組合
只要forkCount不爲0,就能夠和-T組合。
forkCount=0, 或forkCount=1/reuseForks=true,能夠和parallel自由組合。
forkCount的測試進程是按類爲單位執行的,測試類整個整個的傳到測試進程中執行。reuseForks=false或forkCount>1時,就會使用獨立的測試進程,因此parallel=classes就失效了。可是仍是能夠組合parallel=methods/threadCount=n指定每一個測試進程裏的併發線程數。
其餘不經常使用的配置列在最後。
<suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles>
<systemPropertyVariables> <propertyName>firefox</propertyName> </systemPropertyVariables>
<groups>functest,perftest</groups>
TestNG支持在測試時附加自定義的listener, reporter, annotation transformer, method interceptor。默認會使用基本的listener生成HTML和XML報告。
Listener實現org.testng.ITestListener接口,會在測試開始、經過、失敗等時刻實時發送通知。
Reporter實現org.testng.IReporter接口,在整個測試運行完畢以後纔會發送通知,參數爲對象列表,包含整個測試的執行結果情況。
<properties> <property> <name>usedefaultlisteners</name> <value>false</value> <!-- disabling default listeners is optional --> </property> <property> <name>listener</name> <value>com.mycompany.MyResultListener,com.mycompany.MyAnnotationTransformer,com.mycompany.MyMethodInterceptor</value> </property> <property> <name>reporter</name> <value>listenReport.Reporter</value> </property> </properties>
Pom.xml中添加JUnit依賴就能執行Junit測試。
根據引入的Junit依賴版本和是否配置了併發 自動肯定使用JUnit 3.8.x, JUnit 4.x (serial provider) 仍是 JUnit 4.7(junit-core provider with parallel support),也能夠在<plugin>節點裏加入<dependencies>元素強行指定執行版本。(詳細說明:http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html)
<properties> <property> <name>listener</name> <value>com.mycompany.MyResultListener,com.mycompany.MyResultListener2</value> </property> </properties>
<groups>com.mycompany.SlowTests</groups>
public interface SlowTests{} public interface SlowerTests extends SlowTests{} public class AppTest { @Test @Category(com.mycompany.SlowTests.class) public void testSlow() { System.out.println("slow"); } @Test @Category(com.mycompany.SlowerTests.class) public void testSlower() { System.out.println("slower"); } @Test @Category(com.cmycompany.FastTests.class) public void testSlow() { System.out.println("fast"); } }
<argLine>-Djava.security.manager -Djava.security.policy=${basedir}/src/test/resources/java.policy</argLine>
Junit3還能夠以下配置(forkCount爲0時):
<systemPropertyVariables> <surefire.security.manager>java.lang.SecurityManager</surefire.security.manager> </systemPropertyVariables>
mvn -Dsurefire.rerunFailingTestsCount=2 test #(JUnit須要4.x版本)
重跑的log和報告等詳細信息,看這裏http://maven.apache.org/surefire/maven-surefire-plugin/examples/rerun-failing-tests.html
<argLine>-Djava.endorsed.dirs=...</argLine>
<systemPropertyVariables> <propertyName>propertyValue</propertyName> <buildDirectory>${project.build.directory}</buildDirectory> [...] </systemPropertyVariables>
再也不推薦使用的方式
<systemProperties> <property> <name>buildDir</name> <value>String類型的值</value> </property> </systemProperties>
繼承父項目配置的系統屬性
<systemProperties combine.children="append"> <property> [...] </property> </systemProperties>
test classpath包括:
要配置classpath,最好是使用添加依賴的方法。若是必定添加額外的ClassPath,這樣配置:
<additionalClasspathElements> <additionalClasspathElement>path/to/additional/resources</additionalClasspathElement> <additionalClasspathElement>path/to/additional/jar</additionalClasspathElement> </additionalClasspathElements>
移除依賴
<classpathDependencyExcludes> <classpathDependencyExcludes>org.apache.commons:commons-email</classpathDependencyExcludes> </classpathDependencyExcludes>
按scope移除依賴
<classpathDependencyScopeExclude>runtime</classpathDependencyScopeExclude>
默認狀況下,surefire在新的進程中執行,命令mvn -Dmaven.surefire.debug test建立的測試進程會等待遠程調試器(Eclipse)鏈接到5005端口。要配置不一樣的端口命令爲:
mvn -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -Xnoagent -Djava.compiler=NONE" test
若是forkCount選項配置爲0(mvn -DforkCount=0 test),不會建立新的測試進程,測試在maven主線程中執行。命令mvnDebug -DforkCount=0 test會使maven以調試模式運行,能夠將遠程調試器鏈接到maven進程。
可選的有surefire-junit3, surefire-junit4, surefire-junit47和 surefire-testng。指定Provider時,測試框架的依賴配置也不能少。
maven-surefire-plugin的<plugin>節點中添加以下配置。
<dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>2.18.1</version> </dependency> </dependencies>
解決classpath長度超過命令行運行的最大參數長度問題。
方法有兩個,各有優缺點:
一是使用獨立的類加載器,在其中加載classpath內容。
二是使用一個只有META-INF/MANIFEST.MF的jar文件(如booter.jar),在manifest.mf文件中配置classpath。而後以 java -classpath booter.jar MyApp的方式運行。
配置方法
useSystemClassLoader爲fasle, 使用獨立的類加載器。
useSystemClassLoader爲true而且useManifestOnlyJar爲true時 ,使用manifest-only JAR
useSystemClassLoader爲true而且useManifestOnlyJar爲false時,使用最原始的java classpath
執行
mvn -Dsurefire.useSystemClassLoader=false test
或
<useSystemClassLoader>false</useSystemClassLoader> <useManifestOnlyJar>false</useManifestOnlyJar>
這一部分具體信息可查看:http://maven.apache.org/surefire/maven-surefire-plugin/examples/class-loading.html