跳过Maven中某些模块的测试

时间:2009-04-21 14:02:44

标签: maven unit-testing junit maven-2 build-process

我希望我的Maven构建版能够运行大多数单元测试。但是在一个项目中有单元测试速度较慢,我想一般排除它们;并偶尔打开它们。

问题:我该怎么做?

我知道-Dmaven.test.skip=true,但这会关闭所有单元测试。

我也知道跳过集成测试,描述here。但我没有集成测试,只有单元测试,我没有任何显式调用maven-surefire-plugin。 (我正在使用Maven 2和Eclipse-Maven插件)。

5 个答案:

答案 0 :(得分:72)

仅在此模块中跳过测试怎么样?

在这个模块的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,它将不会运行此模块的测试。

答案 1 :(得分:30)

我认为这更容易,并且还可以用于非确定性测试(在我的情况下,FlexUnitTests)

<profile>
   <id>noTest</id>
    <properties>
       <maven.test.skip>true</maven.test.skip>
    </properties>
 </profile>

答案 2 :(得分:4)

如果您有一个大型多模块项目,并且您希望仅在某些模块中跳过测试而无需使用自定义配置和分析更改每个模块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正常运行时,module3module2将跳过测试,即正则表达式所表示的。

这种方法的优点是使其动态和集中(在父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文件或激活任何配置文件。

答案 3 :(得分:2)

使用Surefire插件2.19,您只需使用正则表达式排除您不想要的测试:

mvn '-Dtest=!%regex[.*excludedString.*]' test

上述命令将排除包含 excludedString 的所有测试。

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/

答案 4 :(得分:2)

我对此问题的需求略有不同,可能会有所帮助。我想从命令行中排除来自不同包的几个不同的测试,因此单个通配符不会这样做。

我在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属性中。