如何在maven安装目标中跳过testing,同时在maventesting目标中运行它们?

我有一个在同一个文件夹(src / test / java)中集成和unit testing的多模块maven项目。 集成testing用@Category(IntegrationTest.class)标记。 我想结束以下设置:

  1. 如果我运行mvn install ,我想要所有的testing编译,但我不想执行任何。
  2. 如果我运行mvn test ,我想要所有的testing编译,但只执行unit testing。
  3. 如果我运行mvn integration-test ,我想编译并执行所有的testing。

重要的一点是,我想在没有任何额外的命令行参数在pom.xmlconfiguration。

目前我想到了我的父pom.xml中的以下设置,其中唯一的问题是执行所有testing的#1:

 <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${project.java.version}</source> <target>${project.java.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.14.1</version> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>2.14.1</version> </dependency> </dependencies> <configuration> <includes> <include>**/*.class</include> </includes> <excludedGroups>cz.cuni.xrg.intlib.commons.IntegrationTest</excludedGroups> </configuration> </plugin> <plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>2.14.1</version> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>2.14.1</version> </dependency> </dependencies> <configuration> <groups>cz.cuni.xrg.intlib.commons.IntegrationTest</groups> </configuration> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> <configuration> <includes> <include>**/*.class</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </pluginManagement> </build> 

所有的子模块在它们的pom.xml中都有下面的插件configuration,我相信它应该从父pominheritance:

 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> </plugin> <plugin> <artifactId>maven-failsafe-plugin</artifactId> </plugin> </plugins> </build> 

我尝试使用<skipTests>true</skipTests> ,但它禁用所有目标的testing执行,这不是我想要的(违反#2和#3)。 这也是很奇怪, mvn test荣幸skipTests=true选项…为什么我想要运行它在第一位?

经过几个小时的谷歌search和尝试不同的组合,我很犹豫是否可以不运行mvn installtesting,同时在mvn test运行它们。 我希望有人certificate这个错误。 ;)

我也愿意接受一个解决scheme,在那里mvn install将只执行unit testing,但我不认为它有什么区别。

这听起来像你不了解Maven的构build生命周期的概念。 如果运行mvn install所有生命周期阶段(包括install阶段本身),请在安装阶段之前运行。 这意味着运行以下阶段:

  1. validation
  2. 初始化
  3. 产生来源
  4. stream程源
  5. 生成资源
  6. stream程资源
  7. 工艺类
  8. 生成testing来源
  9. 过程 – testing – 源
  10. 生成testing资源
  11. stream程testing资源
  12. testing编译
  13. 过程检验类
  14. testing
  15. 制备包
  16. 预集成testing
  17. 集成testing
  18. 整合后的testing
  19. 校验
  20. 安装

换句话说就是包含了testintegration-test生命周期阶段。 因此,没有任何补充信息,不可能根据您的意愿更改行为。

这可以通过在Maven中使用configuration文件来实现:

  <project> [...] <profiles> <profile> <id>no-unit-tests</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> </plugin> </plugins> </build> </profile> </profiles> [...] </project> 

所以你的第一个要求:

  1. 如果我运行mvn安装,我想要所有的testing编译,但我不想执行任何。

可以通过使用以下来实现:

 mvn -Pno-unit-test test 
  1. 如果我运行mvntesting,我想要所有的testing编译,但只执行unit testing。

这可以简单地通过使用简单的调用来实现:

 mvn test 

因为集成testing阶段没有运行(参见buid生命周期)。

  1. 如果我运行mvn integration-test,我想编译并执行所有的testing。

这意味着运行默认包括运行test阶段,这将运行unit testing(maven-surefire插件),并进一步运行由maven-failsafe插件处理的集成testing。 但是你应该知道,如果你想调用集成testing,你应该使用以下内容:

 mvn verify 

而是导致您在之前的调用中错过了post-integration-test阶段。

除了上面的内容,你应该遵循unit testing和集成testing的命名规范,其中unit testing的命名应该像下面这样:

 <includes> <include>**/*Test*.java</include> <include>**/*Test.java</include> <include>**/*TestCase.java</include> </includes> 

并且集成testing应该像下面这样命名:

 <includes> <include>**/IT*.java</include> <include>**/*IT.java</include> <include>**/*ITCase.java</include> </includes> 

我希望你已经configuration了maven-failsafe-plugin,像下面这样将maven-failsafe-plugin绑定到正确的生命周期阶段:

 <project> [...] <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.15</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> </plugins> </build> [...] </project> 

正如你所做的那样,但是你应该知道include标签在源代码( .java)上而不是在编译的名字( .class)上。 我不会使用分类注释,只是简单地使用命名约定使得POM更简单和更短。

根据故障安全插件文档

 mvn install -DskipITs 

是你想要的。

本文解释了如何跳过集成testing,无论您使用哪个插件来进行这些testing。 基本上,你所做的是定义一个configuration文件,并把所有的集成testing相关的XML代码在该configuration文件。 当你缺less一个属性-DskipIntegrationTests时,你会激活它。

unit testing可以做同样的事情:编写一个configuration文件,并在缺less-DskipUnitTests时将其激活。

 Then, you could do: mvn install -DskipIntegrationTests -DskipUnitTests (runs install without any tests) mvn test (runs unit tests) mvn post-integration-test (runs all tests) 

OP在他的问题中表示:

如果我运行mvn安装 ,我想要所有的testing编译,但我不想执行任何。
如果我运行mvntesting ,我想要所有的testing编译,但只执行unit testing。
如果我运行mvn integration-test ,我想编译并执行所有的testing。

是完全有效的并且非常容易实现。
编辑:除了第一个条件,其行为maven性质。 这里最好的方法就是简单地mvn install -DskipTests

所有你需要的是在pom.xml代码片段:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.17</version> <executions> <execution> <id>integration-tests</id> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> 

并坚持单元和集成testing的Maven命名约定 (正如@khmarbaise所述)。 所以一般用IT后缀命名集成testing(例如MyIntegrationTestIT.java ),让maven-failsafe完成它的工作。
这样,你甚至不需要JUnit类(尽pipe有时它们可​​能是非常有用的)。

而已 :)

  • mvn test 执行unit testing
  • mvn integration-test执行所有testing
  • mvn failsafe:integration-test 运行集成testing
  • mvn clean verify当你想确定,整个项目是正常的

一些个人build议

就个人而言,我会build议集成testingTestNG而不是JUnit ,主要是由于其非常有用的注释@BeforeSuite@AfterSuite (就是这样,你可以使用TestNG,而无需编写任何XMLconfiguration文件)。


同时将集成testing与unit testing分开进行,可以让您在IDE中轻松运行某些软件包中的所有testing。 通常使用称为test-integration (或integrationtest )的附加目录用于此目的。
用maven也很容易实现:

 <plugin> <!-- adding second test source directory (just for integration tests) --> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.9.1</version> <executions> <execution> <id>add-integration-test-source</id> <phase>generate-test-sources</phase> <goals> <goal>add-test-source</goal> </goals> <configuration> <sources> <source>src/test-integration/java</source> </sources> </configuration> </execution> </executions> </plugin> 

然后将您的集成testing移动到该目录。 它应该看起来像:

 src main test test-integration 

集成testing通常需要更多的内存:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> ... <configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> </configuration> </plugin> 

maven-failsafe-plugin 文档有一个标题为“默认跳过”的部分。

不幸的是,页面描述的步骤不能像写入那样工作。 但是,对这些步骤稍作改动将会使其工作:

pom.xmlproperties部分,添加这个:

<skipITs>true</skipITs>

然后将skipTests属性添加到maven-failsafe-plugin的plugin部分:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <configuration> <skipTests>${skipITs}</skipTests> </configuration> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> 

所以现在,默认的mvn install将执行unit testing,但不是集成testing。

但是mvn install -DskipITs=false会执行unit testing和集成testing。

脚注:糟糕的文档在很长一段时间里为什么Maven很不受欢迎。

mvn test-compile完全是你在找什么。 你可以简单地用mvn test-compilereplacemvn install ,你就完成了。 无需自定义POM文件或任何东西。 下面的链接问题与#1相似:

Maven – 如何编译testing而不运行它们?

应该接受mvn test-compile作为最好的答案,因为Maven支持你本来想做的而没有任何魔法的东西。 你会最终这样做:

 If I run mvn test-compile, I want all tests to compile, but I do not want to execute any. If I run mvn test, I want all tests to compile, but execute only unit tests. If I run mvn integration-test, I want to compile and execute all tests.