我有一个多模块maven项目,同时在同一个文件夹(src / test / java)中进行集成和单元测试。集成测试标有@Category(IntegrationTest.class)
。我想最终得到以下设置:
mvn install
,我希望编译所有测试,但我不想执行任何测试。mvn test
,我希望编译所有测试,但只执行单元测试。mvn integration-test
,我想编译并执行所有测试。 重要的是,我希望在pom.xml
中配置此配置而不需要任何额外的命令行参数。
目前我在我的父pom.xml中提出了以下设置,其中唯一的问题是#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中都有以下插件配置,我相信它应该从父pom继承:
<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>
,但它禁用了所有目标的测试执行,这不是我想要的(违反#2和#3)。同样很奇怪,mvn test
尊重skipTests=true
选项......为什么我要首先运行它?
经过数小时的谷歌搜索和尝试不同的组合后,我甚至犹豫是否有可能不在mvn install
中运行测试,同时在mvn test
中运行它们。我希望有人证明这是错误的。 ;)
我也愿意接受一个解决方案,其中mvn install
只执行单元测试,但我认为它没有多大区别。
答案 0 :(得分:88)
听起来你并不理解Maven中build life-cycle的概念。如果您在安装阶段之前运行mvn install
所有生命周期阶段(包括install
阶段本身)。这意味着运行以下阶段:
这意味着换句话说,test
以及integration-test
生命周期阶段都包括在内。因此,如果没有任何补充信息,就无法按照您的意愿改变行为。
可以通过在Maven中使用配置文件来实现:
<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>
所以你的第一个要求是:
mvn install
,我希望编译所有测试,但我不想执行任何测试。可以通过以下方式实现:
mvn -Pno-unit-test test
mvn test
,我希望编译所有测试,但只执行单元测试。这可以通过使用普通呼叫简单地实现:
mvn test
导致集成测试阶段未运行(请参阅构建生命周期)。
mvn integration-test
,我想编译并执行所有测试。这意味着运行默认值,包括运行test
阶段,该阶段将运行单元测试(maven-surefire-plugin),并进一步运行由maven-failsafe-plugin处理的集成测试。但是你应该知道,如果你想调用集成测试,你应该使用以下命令:
mvn verify
相反,导致您错过了之前通话中的post-integration-test
阶段。
除上述内容外,您应遵循单元和集成测试的命名约定,其中unit tests的名称应如下所示:
<includes>
<include>**/*Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
</includes>
和integration tests的名称应如下所示:
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
我希望您已经配置了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更简单,更短。
答案 1 :(得分:47)
答案 2 :(得分:16)
OP在他的问题中说了什么:
如果我运行 mvn install ,我希望所有测试都能编译,但我不想要 执行任何。
如果我运行 mvn test ,我希望所有测试都能编译,但只执行单元测试 如果我运行 mvn integration-test ,我想编译并执行所有测试。
非常有效且非常容易实现
编辑:除了第一个条件,其行为反对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>
并坚持单位和集成测试的 maven命名约定(正如@khmarbaise已经说过的那样)。因此,通常使用IT
后缀(例如MyIntegrationTestIT.java
)命名集成测试,并让maven-failsafe
完成其工作。
这样,您甚至不需要JUnit类别(尽管有时候它们非常有用)。
那就是它:)
mvn test
执行仅单元测试mvn integration-test
执行所有测试mvn failsafe:integration-test
仅运行 集成测试mvn clean verify
当你想确定整个项目正常工作时
将集成测试与单元测试分开,使您可以在IDE中轻松地在某些软件包中运行所有测试。通常,名为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>
然后将集成测试移动到该目录。它应该看起来像:
src
main
test
test-integration
集成测试通常需要更多内存:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
...
<configuration>
<argLine>-Xmx512m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
答案 3 :(得分:12)
This post解释了如何跳过集成测试,无论您使用哪些插件进行这些测试。
基本上,您要做的是定义一个配置文件,并将所有与集成测试相关的xml代码放在该配置文件中。比在缺少属性-DskipIntegrationTests
时激活它。
您可以对单元测试执行相同的操作:编写配置文件并在缺少-DskipUnitTests
时激活它。
然后,你可以这样做:
mvn install -DskipIntegrationTests -DskipUnitTests # (runs install without any tests)
mvn test # (runs unit tests)
mvn post-integration-test # (runs all tests)
答案 4 :(得分:4)
maven-failsafe-plugin docs有一个标题为&#34;默认跳过的部分。&#34;
可悲的是,页面描述的步骤并没有按照书面形式进行。但是,稍微改变一下这些步骤就可以了:
在properties
的{{1}}部分,添加以下内容:
pom.xml
然后将<skipITs>true</skipITs>
属性添加到maven-failsafe-plugin的skipTests
部分:
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
将执行单元测试和集成测试。
脚注:错误的文档很大程度上说明了为什么Maven在这么长时间内都不那么讨厌。
答案 5 :(得分:2)
mvn test-compile
完全符合您的要求。您只需将mvn install
替换为mvn test-compile
,即可完成。无需自定义pom文件或任何其他内容。下面链接的问题类似于#1:
Maven - How to compile tests without running them ?
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.
答案 6 :(得分:0)
在故障安全插件的配置中不指定执行步骤。例如
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
</plugins>
现在,您特别需要调用mvn failsafe:integration-test来运行集成测试;它们会在其他mvn目标中被跳过。