在 Maven 中跳过某些模块中的测试

Posted

技术标签:

【中文标题】在 Maven 中跳过某些模块中的测试【英文标题】:Skipping tests in some modules in Maven 【发布时间】:2010-10-20 20:09:16 【问题描述】:

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

问题:我该怎么做?

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

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

【问题讨论】:

【参考方案1】:

只在这个模块中跳过测试怎么样?

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

【讨论】:

感谢工作。第一段代码 sn -p 跳过测试;我稍后可能会使用您的进一步建议来定义另一个配置文件。我的困惑在于我的 pom 隐含地调用了surefire。在我的 pom.xml 中没有提到 surefire 插件。尽管如此,正确配置surefire插件的代码还是这样做了。 对于其他人,另一种选择是跳过整个模块,直到您想要构建和验证它:***.com/a/5542779/543935 这里是如何创建 maven 配置文件,只有在它被激活的情况下才会运行测试:***.com/questions/34334257/… 除了项目中的几个模块之外,您如何为所有模块执行此操作? 谁能给我解释一下noTest在这里有什么用处?【参考方案2】:

我认为这更容易,并且还具有为不确定测试工作的好处(在我的例子中,FlexUnitTests)

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

【讨论】:

这里不会跳过测试,不管有没有 -DnoTest=true 那是因为你应该使用 -PnoTest 而不是 -DnoTest=true 将 maven.test.skip 设置为 true 也有跳过测试编译的效果,因为 skipTests 仍然编译测试但不运行它们。【参考方案3】:

如果您有一个大型的多模块项目,并且您希望仅在某些模块中跳过测试,而无需使用自定义配置和分析更改每个模块 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)。

在这种情况下,module1module3 的测试将被跳过,而 module2 的测试将正常运行,即如正则表达式所示。

这种方法的优点是使其动态和集中(在父级pom.xml 中),因此更便于维护:您可以随时通过更改上面的简单正则表达式来添加或删除模块。

显然,如果这不是构建的默认行为(推荐的情况),您总是可以将上面的 sn-p 包装在 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 文件或激活任何配置文件。

【讨论】:

【参考方案4】:

使用 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/

【讨论】:

知道如何跳过多个模式吗? -Dtests 似乎与万无一失的配合不太好。以下导致我的所有测试都被跳过:mvn '-Dtest=!%regex[.*DeviceLogServiceTest.*]' --quiet install -Dsurefire.useFile=false -Dsurefire.printSummary=false -Dmaven.test.skip=false【参考方案5】:

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

我在 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 属性进行一系列测试。

【讨论】:

以上是关于在 Maven 中跳过某些模块中的测试的主要内容,如果未能解决你的问题,请参考以下文章

在 Maven 构建期间跳过子模块

maven:如何通过命令行选项跳过某些项目中的测试?

如何根据某些条件在 MSSQL 游标中跳过一行(迭代)?

如何在 gitlab-ci build 中跳过前面的 maven 目标?

如何在java中跳过过滤器链中的过滤器

如何在rspec测试中跳过服务调用