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

the*_*eko 56 integration-testing maven 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>
Run Code Online (Sandbox Code Playgroud)

所有子模块在他们的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>
Run Code Online (Sandbox Code Playgroud)

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

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

我也愿意接受一个解决方案,在那里mvn install只执行单元测试,但我认为它没有多大区别.

khm*_*ise 93

听起来你并不理解Maven中构建生命周期的概念.如果在安装阶段之前运行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>
Run Code Online (Sandbox Code Playgroud)

所以你的第一个要求:

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

可以通过使用以下方法实现:

mvn -Pno-unit-test test
Run Code Online (Sandbox Code Playgroud)
  1. 如果我运行mvn test,我想要编译所有测试,但只执行单元测试.

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

mvn test
Run Code Online (Sandbox Code Playgroud)

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

  1. 如果我运行mvn integration-test,我想编译并执行所有测试.

这意味着运行默认值,包括运行test将运行单元测试(maven-surefire-plugin)的阶段,并进一步运行由maven-failsafe-plugin处理的集成测试.但是你应该知道,如果你想调用集成测试,你应该使用以下命令:

mvn verify
Run Code Online (Sandbox Code Playgroud)

相反,导致你错过了post-integration-test之前通话的阶段.

除上述内容外,您还应遵循单元测试和集成测试的命名约定,其中单元测试的名称应如下所示:

<includes>
 <include>**/*Test*.java</include>
 <include>**/*Test.java</include>
 <include>**/*TestCase.java</include>
</includes>
Run Code Online (Sandbox Code Playgroud)

集成测试应该命名如下:

<includes>
 <include>**/IT*.java</include>
 <include>**/*IT.java</include>
 <include>**/*ITCase.java</include>
</includes>
Run Code Online (Sandbox Code Playgroud)

我希望你已经配置了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>
Run Code Online (Sandbox Code Playgroud)

正如你所做的那样,但你应该知道include标签在源代码(.java)上工作,而不是在编译名称( .class)上.我不会使用Category注释,只需使用命名约定就可以使pom更简单,更短.

  • 感谢您对构建生命周期的解释.我已经使用配置文件跳过测试,但我希望无需切换配置文件即可实现.我接受你的回答,因为"不可能"也是一个答案.:) (2认同)

小智 49

根据Failsafe插件文档

mvn install -DskipITs
Run Code Online (Sandbox Code Playgroud)

是你想要的.


G. *_*cki 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>
Run Code Online (Sandbox Code Playgroud)

并坚持单位和集成测试的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>
Run Code Online (Sandbox Code Playgroud)

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

src
   main
   test
   test-integration
Run Code Online (Sandbox Code Playgroud)

集成测试通常需要更多内存:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    ...
    <configuration>
        <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine>
    </configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)


Emi*_*anu 12

这篇文章解释了如何跳过集成测试,无论你使用什么插件进行这些测试.

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

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

然后,你可以这样做:

mvn install -DskipIntegrationTests -DskipUnitTests # (runs install without any tests)
mvn test # (runs unit tests)
mvn post-integration-test # (runs all tests)
Run Code Online (Sandbox Code Playgroud)


rdg*_*uam 5

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

可悲的是,该页面描述的步骤并不像书面的那样工作。但是,对这些步骤稍作更改即可使其起作用:

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

<skipITs>true</skipITs>

然后将该skipTests属性添加到pluginmaven-failsafe-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>
Run Code Online (Sandbox Code Playgroud)

所以现在,mvn install默认情况下将执行单元测试,而不是集成测试。

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

脚注:糟糕的文档在很大程度上解释了为什么 Maven 如此不受欢迎这么长时间。