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

问题描述 投票:52回答:7

我有一个多模块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只执行单元测试,但我认为它没有太大的区别。

maven integration-testing maven-surefire-plugin maven-failsafe-plugin
7个回答
89
投票

听起来你并不理解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. 安装

换句话说,包括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更简单,更短。


48
投票

根据Failsafe Plugin documentation

mvn install -DskipITs

是你想要的。


16
投票

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

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

是完全有效的,非常容易实现。 编辑:除了第一个条件,它反对maven性质。这里最好的方法就是做qazxsw poi

您只需要关注mvn install -DskipTests中的代码段:

pom.xml

并坚持单位和集成测试的maven命名约定(如@khmarbaise已经说明的那样)。所以通常用<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> 后缀(例如IT)命名你的集成测试,让MyIntegrationTestIT.java完成它的工作。 这样,您甚至不需要JUnit类别(尽管有时候它们非常有用)。

而已 :)

  • maven-failsafe只执行单元测试
  • mvn test执行所有测试
  • mvn integration-test只运行集成测试
  • mvn failsafe:integration-test,当你想确定,整个项目正常

一些个人建议

将集成测试与单元测试分开,可以让您在IDE中轻松地在某些软件包中运行所有测试。通常使用名为mvn clean verify(或test-integration)的附加目录来实现此目的。 使用maven也很容易实现:

integrationtest

然后将集成测试移动到该目录。它应该看起来像:

<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

12
投票

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> ... <configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> </configuration> </plugin> 解释了如何跳过集成测试,无论您使用哪种插件进行这些测试。

基本上,您要做的是定义一个配置文件,并将所有与集成测试相关的xml代码放在该配置文件中。比财产This post缺失时激活它。

您可以对单元测试执行相同的操作:编写配置文件并在缺少-DskipIntegrationTests时激活它。

然后,你可以这样做:

-DskipUnitTests

4
投票

maven-failsafe-plugin mvn install -DskipIntegrationTests -DskipUnitTests # (runs install without any tests) mvn test # (runs unit tests) mvn post-integration-test # (runs all tests) 有一个标题为“默认跳过”的部分。

遗憾的是,页面描述的步骤不能像写的那样工作。但是,稍微更改这些步骤将使其工作:

docsproperties部分,添加:

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在这么长时间内如此不喜欢。


2
投票

mvn install -DskipITs=false完全符合您的要求。你可以简单地用mvn test-compile替换mvn install,你就完成了。无需自定义pom文件或任何其他内容。下面链接的问题类似于#1:

mvn test-compile

Maven - How to compile tests without running them ? 应该被认为是最好的答案,因为Maven完全支持你想做的本地和没有任何魔法。你会最终得到这个:

mvn test-compile

0
投票

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

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.

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

© www.soinside.com 2019 - 2024. All rights reserved.