【问题标题】:How can I skip tests in maven install goal, while running them in maven test goal?如何在 Maven 安装目标中跳过测试,同时在 Maven 测试目标中运行它们?
【发布时间】:2013-06-11 15:21:52
【问题描述】:

我有一个多模块 maven 项目,在同一文件夹 (src/test/java) 中有集成和单元测试。集成测试标有@Category(IntegrationTest.class)。我想完成以下设置:

  1. 如果我运行mvn install,我希望编译所有测试,但我不想执行任何测试。
  2. 如果我运行mvn test,我希望编译所有测试,但只执行单元测试。
  3. 如果我运行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>

我尝试使用&lt;skipTests&gt;true&lt;/skipTests&gt;,但它禁用了所有目标的测试执行,这不是我想要的(违反#2 和#3)。这也很奇怪,mvn test 尊重 skipTests=true 选项...我为什么要首先运行它??

经过数小时的谷歌搜索和尝试不同的组合,我犹豫是否可以不在mvn install 中运行测试,同时在mvn test 中运行它们。我希望有人证明这是错误的。 ;)

我也愿意接受一个解决方案,mvn install 将只执行单元测试,但我认为这没有太大区别。

【问题讨论】:

  • mvn 全新安装 -DskipITs 。 :)
  • 这是 gradle 成为更好构建工具的一个示例。

标签: maven integration-testing maven-surefire-plugin maven-failsafe-plugin


【解决方案1】:

听起来你不明白 Maven 中build life-cycle 的概念。如果您运行mvn install,所有生命周期阶段(包括install 阶段本身)都会在安装阶段之前运行。这意味着运行以下阶段:

  1. 验证
  2. 初始化
  3. 生成源
  4. 流程源
  5. 生成资源
  6. 流程资源
  7. 编译
  8. 进程类
  9. 生成测试源
  10. 过程测试源
  11. 生成测试资源
  12. 流程测试资源
  13. 测试编译
  14. 过程测试类
  15. 测试
  16. 准备包
  17. 包
  18. 预集成测试
  19. 集成测试
  20. 集成后测试
  21. 验证
  22. 安装

这意味着包括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>

所以你的第一个要求:

  1. 如果我运行mvn install,我希望编译所有测试,但我不想执行任何测试。

可以通过以下方式实现:

mvn -Pno-unit-test test
  1. 如果我运行mvn test,我希望编译所有测试,但只执行单元测试。

这可以通过使用普通调用来简单地实现:

mvn test

导致集成测试阶段未运行(请参阅构建生命周期)。

  1. 如果我运行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)。我不会使用 Category 注释,只是简单地使用命名约定使 pom 更简单更短。

【讨论】:

  • 感谢您对构建生命周期的解释。我已经使用配置文件跳过测试,但我希望它可以在不需要切换配置文件的情况下实现。我接受你的回答,因为“不可能”也是一个答案。 :)
  • 参数“-Dmaven.test.skip=true”跳过surefire插件运行的测试。
【解决方案2】:

根据Failsafe Plugin documentation

mvn install -DskipITs

是你想要的。

【讨论】:

【解决方案3】:

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】:

    OP 在他的问题中所说的:

    如果我运行 mvn install,我希望所有测试都能编译,但我不想 执行任何。
    如果我运行 mvn test,我希望编译所有测试,但只执行单元测试。
    如果我运行 mvn integration-test,我想编译并执行所有测试。

    是完全有效的并且非常容易实现。
    编辑:除了第一个条件,它违背了 maven 的性质。这里最好的方法是简单地做mvn install -DskipTests

    您只需要在pom.xml 中关注sn-p:

    <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>
    

    并坚持 ma​​ven 命名约定 进行单元和集成测试(正如 @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>
    

    【讨论】:

    • 喜欢这个答案!
    【解决方案5】:

    maven-failsafe-plugin docs 有一个标题为“默认跳过”的部分。

    遗憾的是,该页面描述的步骤并不像书面的那样工作。但是,对这些步骤稍作改动即可使其发挥作用:

    在pom.xml 的properties 部分,添加以下内容:

    &lt;skipITs&gt;true&lt;/skipITs&gt;

    然后将skipTests 属性添加到maven-failsafe-plugin 的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 默认会执行单元测试,而不是集成测试。

    但是mvn install -DskipITs=false 将同时执行单元测试和集成测试。

    脚注:糟糕的文档是 Maven 长期以来不受欢迎的主要原因。

    【讨论】:

      【解决方案6】:

      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.
      

      【讨论】:

        【解决方案7】:

        不要在故障安全插件的配置中指定执行步骤。例如

            <plugins>
                <plugin>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>3.0.0-M3</version>
                </plugin>
            </plugins>
        

        现在,您特别需要调用 mvn failsafe:integration-test 来运行集成测试;它们将在其他 mvn 目标中被跳过。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-28
          • 2011-04-16
          • 1970-01-01
          • 2023-03-02
          • 1970-01-01
          • 2011-11-19
          • 2019-09-04
          相关资源
          最近更新 更多