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

时间:2013-06-14 21:31:29

标签: 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,我想编译并执行所有测试。
  4. 重要的是,我希望在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只执行单元测试,但我认为它没有多大区别。

7 个答案:

答案 0 :(得分:88)

听起来你并不理解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,我希望编译所有测试,但我不想执行任何测试。
    2. 可以通过以下方式实现:

      mvn -Pno-unit-test test
      
      1. 如果我运行mvn test,我希望编译所有测试,但只执行单元测试。
      2. 这可以通过使用普通呼叫简单地实现:

        mvn test
        

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

        1. 如果我运行mvn integration-test,我想编译并执行所有测试。
        2. 这意味着运行默认值,包括运行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)。我不会使用类别注释,只需使用命名约定就可以使pom更简单,更短。

答案 1 :(得分:47)

根据Failsafe Plugin documentation

mvn install -DskipITs

是你想要的。

答案 2 :(得分:16)

OP在他的问题中说了什么:

  

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

非常有效且非常容易实现 编辑:除了第一个条件,其行为反对maven性质。这里最好的方法就是mvn install -DskipTests

您需要的只是pom.xml中的代码段:

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

并坚持单位和集成测试的 maven命名约定(正如@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>

答案 3 :(得分:12)

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 :(得分:4)

maven-failsafe-plugin docs有一个标题为&#34;默认跳过的部分。&#34;

可悲的是,页面描述的步骤并没有按照书面形式进行。但是,稍微改变一下这些步骤就可以了:

properties的{​​{1}}部分,添加以下内容:

pom.xml

然后将<skipITs>true</skipITs>属性添加到maven-failsafe-plugin的skipTests部分:

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将执行单元测试和集成测试。

脚注:错误的文档很大程度上说明了为什么Maven在这么长时间内都不那么讨厌。

答案 5 :(得分:2)

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.

答案 6 :(得分:0)

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

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

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