我希望我的 Maven 构建能够运行大多数单元测试。但是一个项目中的单元测试速度较慢,我一般想将它们排除在外;并偶尔打开它们。
问题:我该怎么做?
我知道 -Dmaven.test.skip=true
,但这会关闭所有单元测试。
我也知道跳过集成测试,如 here 所述。但是我没有集成测试,只有单元测试,而且我没有对 maven-surefire-plugin 的任何显式调用。 (我将 Maven 2 与 Eclipse-Maven 插件一起使用)。
只在这个模块中跳过测试怎么样?
在这个模块的 pom.xml 中:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
最终,您可以创建一个禁用测试的配置文件(仍然是模块的 pom.xml):
<project>
[...]
<profiles>
<profile>
<id>noTest</id>
<activation>
<property>
<name>noTest</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
[...]
</project>
对于后一种解决方案,如果您运行 mvn clean package
,它将运行所有测试。如果您运行 mvn clean package -DnoTest=true
,它将不会运行此模块的测试。
我认为这更容易,并且还具有为不确定测试工作的好处(在我的情况下,FlexUnitTests)
<profile>
<id>noTest</id>
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
</profile>
如果您有一个大型多模块项目,并且您希望仅在某些模块中跳过测试,而无需使用自定义配置和分析更改每个模块 pom.xml
文件,您可以将以下内容添加到父 pom.xml
文件:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>regex-property</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>maven.test.skip</name>
<value>${project.artifactId}</value>
<regex>(module1)|(module3)</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
多亏了 build-helper-maven-plugin
,您实际上会在构建期间通过 project.artifactId
属性(在构建期间指向每个 artifactId
模块)动态检查您是否在某个模块中,然后正则表达式将寻求匹配某些值(您要跳过测试的模块名称)并相应地填充 maven.test.skip
属性(将其设置为 true
)。
在这种情况下,将跳过 module1
和 module3
的测试,同时为 module2
正常运行,即如正则表达式所示。
这种方法的优点是使其动态和集中(在父 pom.xml
中),因此更便于维护:您可以随时通过更改上面的简单正则表达式来添加或删除模块。
显然,如果这不是构建的默认行为(推荐的情况),您总是可以将上面的代码段包装在 maven profile 中。
您还可以更进一步,根据您的输入进行动态行为:
<properties>
<test.regex>none</test.regex>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>regex-property</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>maven.test.skip</name>
<value>${project.artifactId}</value>
<regex>${test.regex}</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
在这里,我们实际上是用属性 test.regex
替换正则表达式值,默认值为 none
(或者任何不匹配任何模块名称的值,或者也需要默认的跳过匹配)。
然后从命令行我们可以
mvn clean test -Dtest.regex="(module1)" > will skip tests only for module1
mvn clean test -Dtest.regex="(module1)|(module2)" > will skip tests on module1 and module2
mvn clean test -Dtest.regex="(module1)|(module2)|(module3)" > will skip the three module tests
mvn clean test -Dtest.regex=".+" > will skip all module tests
mvn clean test > would not skip anything (or fall back on default behavior)
也就是说,您可以在运行时决定,无需更改 pom.xml
文件或激活任何配置文件。
使用 Surefire 插件 2.19,您可以使用正则表达式简单地排除您不想要的测试:
mvn '-Dtest=!%regex[.*excludedString.*]' test
上述命令将排除所有包含 excludeString 的测试。
NB1 如果使用双引号(“)而不是撇号('),则该命令将无法正确解释并产生意外结果。(使用 bash 3.2.57 测试)
NB2 应特别注意使用多个版本的 surefire 插件的项目。早于 2.19 的 surefire 版本将不会执行任何测试,因为它们不支持正则表达式。
版本管理(在父 pom 文件中添加它可能是个好主意):
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
跳过测试的构建命令示例:https://artbcode.wordpress.com/2016/11/28/how-to-skip-a-subset-of-the-unit-tests/
-Dtests
似乎不能很好地与surefire 配合使用。以下导致我的所有测试都被跳过:mvn '-Dtest=!%regex[.*DeviceLogServiceTest.*]' --quiet install -Dsurefire.useFile=false -Dsurefire.printSummary=false -Dmaven.test.skip=false
我对这个问题的需求略有不同,这可能会有所帮助。我想从命令行中排除来自不同包的一些不同测试,所以单个通配符不会这样做。
我在排除的 Maven Failsafe 文档规则中发现,您可以指定以逗号分隔的正则表达式或通配符排除列表:https://maven.apache.org/surefire/maven-failsafe-plugin/examples/inclusion-exclusion.html
所以我的 pomfile 看起来像这样:
<excludes>
<exclude>${exclude.slow.tests}</exclude>
</excludes>
我的命令行包括这个:
mvn install "-Dexclude.slow.tests=**/SlowTest1.java, **/package/ofslowtests/*.java, **/OtherSlowTest.java"
对我来说,关键因素是在一个排除语句中对一个 Maven 属性进行一系列测试。
noTest
有什么用吗?