【问题标题】: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. 安装

这意味着包括testintegration-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.xmlproperties 部分,添加以下内容:

    &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
          相关资源
          最近更新 更多