maven - 如何在 Maven 安装目标中跳过测试,同时在 Maven 测试目标中运行测试?

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

我有一个多模块 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>

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

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

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

最佳答案

听起来你不明白 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. 安装

换句话说,这意味着包括测试以及集成测试生命周期阶段。因此,如果没有任何补充信息,就不可能按照您的意愿改变行为。

可以通过使用 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
  • 如果我运行 mvn test,我希望编译所有测试,但仅执行单元测试。
  • 这可以通过使用简单的调用来简单地实现:

    mvn test
    

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

  • 如果我运行 mvn Integration-test,我想编译并执行所有测试。
  • 这意味着运行默认值,其中包括运行 test 阶段,该阶段将运行单元测试(maven-surefire-plugin),并进一步运行由 maven-failsafe-plugin 处理的集成测试。但您应该注意,如果您想调用集成测试,您应该使用以下命令:

    mvn verify
    

    相反,因为您错过了上次调用中的集成后测试阶段。

    除了上述内容之外,您还应该遵循单元和集成测试的命名约定,其中 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 绑定(bind)到正确的生命周期阶段所需的:

    <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 更简单、更短。

    关于maven - 如何在 Maven 安装目标中跳过测试,同时在 Maven 测试目标中运行测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17117589/

    相关文章:

    java - 目标 org.springframework.boot 的执行默认值 :spring-boot-maven-plugin:1. 0.2.RELEASE:repackage failed: Source must refer to an existing file

    java - 错误: SLF4J: Class path contains multiple SLF4J bindings

    maven - 如何使用 tomcat8-maven-plugin 指定在另一个项目中构建的 WAR 以进行集成测试?

    Maven surefire 2.12 不使用 -Dtest 参数运行特定测试

    java - 为 Runnable Jars 使用不同的属性文件,Maven Eclipse

    maven - 如何解决 Maven 3 中的本地 Artifact ?

    Grails - 域对象未保存在集成测试中

    maven - 阻止单元测试但允许在 Maven 中进行集成测试

    java - 我如何在我的 Java/Maven/Surefire 项目中利用 CircleCI 并行性?

    java - 第谷跳过测试