在Maven测试目标中运行测试时,如何跳过Maven安装目标中的测试?
我在同一个文件夹(src/test/java)中有一个包含集成和单元测试的多模块Maven项目.集成测试用@Category(IntegrationTest.class)
标记.我想要完成以下设置:
I have a multi-module maven project with both integration and unit tests in the same folder (src/test/java). Integration tests are marked with @Category(IntegrationTest.class)
. I want to end up with the following setup:
- 如果我运行
mvn install
,我希望所有测试都可以编译,但是我不想执行任何测试. - 如果我运行
mvn test
,我希望所有测试都可以编译,但仅执行单元测试. - 如果我运行
mvn integration-test
,我想编译并执行所有测试.
- If I run
mvn install
, 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.
重要的一点是,我希望在pom.xml
中配置它而没有任何额外的命令行参数.
The important point is, I want this configured in the pom.xml
without any extra commandline arguments.
目前,我在父pom.xml中提出了以下设置,唯一的问题是#1,其中执行了所有测试:
Currently I came up with the following setup in my parent pom.xml, where the only problem is #1, where all tests are executed:
<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:
All child modules have the following plugin configuration in their pom.xml, which I believe should inherit from the parent 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
选项...为什么我要首先运行它?
I tried using <skipTests>true</skipTests>
, but it disables test execution for all goals, which is not what I want (violates #2 and #3). It is also quite weird, that mvn test
honors the skipTests=true
option...why would I want to run it in the first place??
经过数小时的谷歌搜索和尝试不同的组合之后,我犹豫是否有可能不在mvn install
中运行测试,而同时在mvn test
中运行测试.我希望有人证明这是错误的. ;)
After hours of googling and trying different combinations, I am hesitant whether it is even possible to not run tests in mvn install
, while at the same time run them in mvn test
. I hope someone proves this wrong. ;)
我也愿意接受一个解决方案,其中mvn install
仅执行单元测试,但我认为这没有太大区别.
I am also willing to accept a solution, where mvn install
would execute only unit tests, but I don't think it makes much difference.
It sounds like you didn't understand the concept of the build life-cycle in Maven. If you run mvn install
all life-cycle phases (including the install
phase itself) run before the install phase. This means running the following phases:
- 验证
- 初始化
- 生成源
- 过程源
- 生成资源
- 过程资源
- 编译
- 流程类
- 生成测试源
- process-test-sources
- 生成测试资源
- 过程测试资源
- 测试编译
- 过程测试类
- 测试
- 准备包装
- 包裹
- 集成前测试
- 集成测试
- 集成后测试
- 验证
- 安装
- 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
- prepare-package
- package
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install
这意味着包括test
以及integration-test
生命周期阶段.因此,如果没有任何补充信息,就无法按您希望的方式更改行为.
which means in other words the test
as well as integration-test
life-cycle phases are included. So without any supplemental information it's not possible to change the behaviour as you wish it.
可以通过使用Maven中的配置文件来实现:
It could be achieved by using a profile in 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
,我希望所有测试都可以编译,但是我不想执行任何测试.
- If I run
mvn install
, I want all tests to compile, but I do not want to execute any.
可以通过以下方法实现:
can be achieved by using the following:
mvn -Pno-unit-test test
- 如果我运行
mvn test
,我希望所有测试都可以编译,但仅执行单元测试.
- If I run
mvn test
, I want all tests to compile, but execute only unit tests.
这可以简单地通过使用普通调用来实现:
This can simply achieved by using the plain call:
mvn test
因为集成测试阶段未运行(请参阅构建生命周期).
cause the integration tests phase is not run (see the build life cycle).
- 如果我运行
mvn integration-test
,我想编译并执行所有测试.
- If I run
mvn integration-test
, I want to compile and execute all tests.
这意味着运行默认值,包括运行test
阶段,该阶段将运行单元测试(maven-surefire-plugin),并运行由maven-failsafe-plugin处理的集成测试.但是您应该知道,如果要调用集成测试,则应使用以下命令:
This means running the default which includes running the test
phase which will run the unit tests (maven-surefire-plugin) and furthermore running the integration test which are handled by the maven-failsafe-plugin. But you should be aware that if you like to call the integration tests you should using the following command:
mvn verify
相反,因为您错过了上一个通话中的post-integration-test
阶段.
instead, cause you missed the post-integration-test
phase in your previous call.
Apart from the above you should follow the naming conventions for unit and integration tests where unit tests should be named like the following:
<includes>
<include>**/*Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
</includes>
和集成测试应该命名如下:
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
我希望您已经配置了如下所示的maven-failsafe-plugin,以便将maven-failsafe-plugin绑定到正确的生命周期阶段:
I hope you have configured the maven-failsafe-plugin like the following which is needed to bound the maven-failsafe-plugin to the correct life-cycle-phases:
<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).我不会使用Category注释,仅使用命名约定就可以使pom更加简单和简短.
as you correctly did, but you should be aware that the include
tags work on the source code (.java) and not on the compiled names (.class). I wouldn't use the Category annotation, just simply using the naming conventions makes the pom simpler and shorter.