【问题标题】:How do I get my Maven Integration tests to run如何让我的 Maven 集成测试运行
【发布时间】:2009-09-09 11:56:20
【问题描述】:

我有一个 maven2 多模块项目,在我的每个子模块中,我都有名为 Test.javaIntegration.java 的 JUnit 测试,分别用于单元测试和集成测试。当我执行时:

mvn test

子模块中的所有 JUnit 测试*Test.java 都已执行。当我执行

mvn test -Dtest=**/*Integration

Integration.java 测试都不会在子模块中执行。

这些对我来说似乎是完全相同的命令,但带有 -Dtest=/*Integration** 的命令不起作用,它显示 0 个正在父级别运行的测试,而没有任何测试

【问题讨论】:

标签: java maven-2 testing surefire


【解决方案1】:

Maven build lifecycle 现在包括用于运行集成测试的“集成测试”阶段,这些测试与在“测试”阶段运行的单元测试分开运行。它在“package”之后运行,因此如果您运行“mvn verify”、“mvn install”或“mvn deploy”,集成测试将一路运行。

默认情况下,集成测试运行名为 **/IT*.java**/*IT.java**/*ITCase.java 的测试类,但可以配置。

有关如何连接这一切的详细信息,请参阅Failsafe pluginFailsafe usage page(在我撰写本文时未正确链接上一页),还请查看this Sonatype blog post

【讨论】:

  • @WillV 正确。 Codehaus 的墓地。 maven-failsafe-plugin 现在在 Apache 中。对不起。 :)
  • 默认情况下mvn integration-test 也运行单元测试(通过surefire 使用),但mvn failsafe:integration-test 只运行故障安全集成测试。
  • 令人难以置信的是,Failsafe 插件文档、使用页面和常见问题解答并没有提到它运行名为 */IT.java、**/*IT.java 和**/*ITCase.java...
  • 如果它在package 阶段之后运行,这意味着我应该将我所有的IT java 源代码放在src/main/java 下而不是src/test/java 下,对吗?
  • @HennoVermeulen 我也对如何命名测试感到困惑。它在Inclusions and Exclusions of Tests 中有描述。很高兴可以覆盖默认值,但如果他们能早点提及默认值就更好了。
【解决方案2】:

您可以设置 Maven 的 Surefire 以分别运行单元测试和集成测试。在标准单元测试阶段,您运行与集成测试模式不匹配的所有内容。然后,您创建第二个测试阶段,它只运行集成测试。

这是一个例子:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <excludes>
          <exclude>**/*IntegrationTest.java</exclude>
        </excludes>
      </configuration>
      <executions>
        <execution>
          <id>integration-test</id>
          <goals>
            <goal>test</goal>
          </goals>
          <phase>integration-test</phase>
          <configuration>
            <excludes>
              <exclude>none</exclude>
            </excludes>
            <includes>
              <include>**/*IntegrationTest.java</include>
            </includes>
          </configuration>
        </execution>
      </executions>
    </plugin>

【讨论】:

  • 我按照你说的配置了这个,只有 *Test 而不是 *Integration.java 文件在执行时会运行: mvn install 我需要运行我的 *Test.java 作为默认值,但对于我的 nightlty build 我需要同时运行 *Test.java 和 *Integration.java。我必须执行 mvn install 然后 cd 到每个子目录并执行 mvn -Dtest=**/*Integration test
  • 您应该使用故障安全插件进行集成测试,而不是万无一失的插件。直到后期集成阶段完成之前,它不会使构建失败;允许您在构建失败之前拆除测试资源(例如 Web 服务器)。因此,故障安全。
  • 对我来说,作为预集成阶段的一部分,码头服务器启动。最后的日志行是:[INFO] Started Jetty Server。之后,什么也没有发生。它卡住了。 maven surefire 故障安全插件不会执行测试,也不会停止码头服务器。知道有什么问题吗?我使用的配置与您指定的相同。
  • 这个答案已经过时了,应该更新或删除。
  • 这个有什么帮助吗? stackoverflow.com/questions/48639730/…
【解决方案3】:

我已经完成了您想做的事情,而且效果很好。单元测试“*Tests”始终运行,而“*IntegrationTests”仅在您执行 mvn verify 或 mvn install 时运行。这是我 POM 中的 sn-p。 serg10 几乎是正确的....但不完全正确。

  <plugin>
    <!-- Separates the unit tests from the integration tests. -->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
       <!-- Skip the default running of this plug-in (or everything is run twice...see below) -->
       <skip>true</skip>
       <!-- Show 100% of the lines from the stack trace (doesn't work) -->
       <trimStackTrace>false</trimStackTrace>
    </configuration>
    <executions>
       <execution>
          <id>unit-tests</id>
          <phase>test</phase>
          <goals>
             <goal>test</goal>
          </goals>
          <configuration>
                <!-- Never skip running the tests when the test phase is invoked -->
                <skip>false</skip>
             <includes>
                   <!-- Include unit tests within integration-test phase. -->
                <include>**/*Tests.java</include>
             </includes>
             <excludes>
               <!-- Exclude integration tests within (unit) test phase. -->
                <exclude>**/*IntegrationTests.java</exclude>
            </excludes>
          </configuration>
       </execution>
       <execution>
          <id>integration-tests</id>
          <phase>integration-test</phase>
          <goals>
             <goal>test</goal>
          </goals>
          <configuration>
            <!-- Never skip running the tests when the integration-test phase is invoked -->
             <skip>false</skip>
             <includes>
               <!-- Include integration tests within integration-test phase. -->
               <include>**/*IntegrationTests.java</include>
             </includes>
          </configuration>
       </execution>
    </executions>
  </plugin>

祝你好运!

【讨论】:

  • 正是我试图做的,但我的集成测试在 mvn 测试阶段继续运行,因为我没有跳过默认值。我认为配置测试执行会覆盖它。正如您所解释的,它只是添加了一个新的执行(因此一切都会运行两次)。所以对我来说,skip 是缺失的部分。 +1 因为这个配置回答了 100% 的问题
  • 那么请随意勾选此回复作为答案!
  • 对我来说,作为预集成阶段的一部分,码头服务器启动。最后的日志行是:[INFO] Started Jetty Server。之后,什么也没有发生。它卡住了。 maven surefire 故障安全插件不会执行测试,也不会停止码头服务器。知道有什么问题吗?我使用的配置与您指定的相同。
  • @Tarun - 就你的问题提出一个新问题
  • 这应该是公认的答案。相关的 maven 目标是:clean compile integration-test -Dmaven.test.failure.ignore=false
【解决方案4】:

您可以使用 JUnit 类别和 Maven 轻松拆分它们。
这通过拆分单元和集成测试在下面非常非常简要地显示。

定义一个标记接口

使用类别对测试进行分组的第一步是创建标记界面。
该接口将用于标记您希望作为集成测试运行的所有测试。

public interface IntegrationTest {}

标记您的测试课程

将类别注释添加到测试类的顶部。它采用新界面的名称。

import org.junit.experimental.categories.Category;

@Category(IntegrationTest.class)
public class ExampleIntegrationTest{

    @Test
    public void longRunningServiceTest() throws Exception {
    }

}

配置 Maven 单元测试

这个解决方案的美妙之处在于,单元测试方面并没有真正改变。
我们只需向 maven surefire 插件添加一些配置,使其忽略任何集成测试。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.11</version>
    <configuration>
        <includes>
            <include>**/*.class</include>
        </includes>
        <excludedGroups>
            com.test.annotation.type.IntegrationTest
        </excludedGroups>
    </configuration>
</plugin>

当您执行mvn clean test 时,只会运行未标记的单元测试。

配置 Maven 集成测试

同样,此配置非常简单。
我们使用标准故障安全插件并将其配置为仅运行集成测试。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <includes>
            <include>**/*.class</include>
        </includes>
        <groups>
            com.test.annotation.type.IntegrationTest
        </groups>
    </configuration>
</plugin>

配置使用标准执行目标在构建的集成测试阶段运行故障安全插件。

您现在可以发送mvn clean install
这次除了单元测试运行之外,集成测试也在集成测试阶段运行。

【讨论】:

  • 我认为 JUnit 对我来说已经没有什么秘密了。好地方!
  • 这只有在标记接口已经存在于 Maven 可用的地方时才有效。如果您的标记接口存在于同一多模块构建的另一个模块中,则它不起作用。
  • @EngineerBetter_DJ 你是什么意思?如果你有一个基于多项目的 Maven 配置,你就不能这样做?
【解决方案5】:

您应该使用maven surefire plugin 运行单元测试,使用maven failsafe plugin 运行集成测试。

如果您希望使用标志来切换这些测试的执行,请按照下面的操作。

Maven 配置

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <skipTests>${skipUnitTests}</skipTests>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <includes>
                    <include>**/*IT.java</include>
                </includes>
                <skipTests>${skipIntegrationTests}</skipTests>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <properties>
            <skipTests>false</skipTests>
            <skipUnitTests>${skipTests}</skipUnitTests>
            <skipIntegrationTests>${skipTests}</skipIntegrationTests>
        </properties>

因此,将根据以下标志规则跳过或切换测试:

可以通过以下标志跳过测试:

  • -DskipTests 跳过单元测试和集成测试
  • -DskipUnitTests 跳过单元测试但执行集成测试
  • -DskipIntegrationTests 跳过集成测试但执行单元测试

运行测试

在下面运行以执行单元测试

mvn clean test

您可以执行以下命令来运行测试(单元和集成)

mvn clean verify

为了只运行集成测试,请遵循

mvn failsafe:integration-test

或者跳过单元测试

mvn clean install -DskipUnitTests

另外,为了在mvn install 期间跳过集成测试,请关注

mvn clean install -DskipIntegrationTests

您可以使用

跳过所有测试
mvn clean install -DskipTests

【讨论】:

  • 正是我一直在寻找可能几个小时的解决方案。工作正常!谢谢你 Liquidpie。
  • 更新:skipXXTests 技巧不再起作用。从故障保护的 3.0.0 版开始,&lt;skipTests&gt; 选项已被删除。现在,我们需要使用-DskipITs 跳过集成测试,-DskipTests 跳过所有测试,mvn integration-test 只运行它(无单元测试)。
【解决方案6】:

您应该尝试使用maven failsafe plugin。您可以告诉它包含一组特定的测试。

【讨论】:

  • +1 这是我使用的。效果很好,并允许您进行前/后设置,例如启动和关闭本地 servlet 容器。
  • maven-failsafe-plugin 已转到Plugin Graveyard
  • 墓地页面只是说failsafe 插件已移至maven-failsafe-plugin。看起来maven-failsafe-plugin 仍然有效(文档上次推送时间是 2014 年 3 月)。
【解决方案7】:

默认情况下,Maven 只运行类名中有 Test 的测试。

重命名为 IntegrationTest,它可能会工作。

或者,您可以更改 Maven 配置以包含该文件,但将测试命名为 SomethingTest 可能更容易更好。

来自Inclusions and Exclusions of Tests

默认情况下,Surefire 插件将 自动包含所有测试类 具有以下通配符模式:

  • \*\*/Test\*.java - 包括其所有子目录和所有 java 以“Test”开头的文件名。
  • \*\*/\*Test.java - 包括其所有子目录和所有 java 以“Test”结尾的文件名。
  • \*\*/\*TestCase.java - 包括其所有子目录和所有 java 以“TestCase”结尾的文件名。

如果测试类不去 命名约定,然后配置 Surefire 插件并指定测试 你想包括。

【讨论】:

  • 嗨,谢谢,我有两种测试正常的 POJO Junit 测试,称为 SomethingTest.java,它们会被触发。我还有一个名为 SomethingIntegration.java 的集成测试,它不会被解雇。 SomethingTest.java 通过 mvn test 或 mvn install 被触发。第二个测试不会被解雇。 mvn test -Dtest=**/*积分
  • .. 并且“Maven 只运行在类名中某处有 Test 的测试”,你的意思是“Maven surefire 插件只运行在类名中某处有 Test 的测试”。
  • 它不是“类名中的某处”而是“类名以 Test 结尾”,例如 MyTest 有效,但 MyTests 无效
【解决方案8】:

使用 Maven 运行集成测试的另一种方法是使用配置文件功能:

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <includes>
                    <include>**/*Test.java</include>
                </includes>
                <excludes>
                    <exclude>**/*IntegrationTest.java</exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

<profiles>
    <profile>
        <id>integration-tests</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <includes>
                            <include>**/*IntegrationTest.java</include>
                        </includes>
                        <excludes>
                            <exclude>**/*StagingIntegrationTest.java</exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
...

运行 'mvn clean install' 将运行默认构建。如上所述,集成测试将被忽略。运行 'mvn clean install -P integration-tests' 将包括集成测试(我也忽略了我的暂存集成测试)。此外,我有一个 CI 服务器每晚运行我的集成测试,为此我发出命令 'mvn test -P integration-tests'

【讨论】:

  • 为什么不使用集成测试阶段?然后配置文件可以用于像 Arquillian 一样对各种应用服务器进行集成测试等。我不是 Maven 专家,但我认为专家可能会说这不是很“Maven-y”。
  • @Joshua 我想我这样做是因为我的集成测试至少需要 5 分钟才能运行,并且我每天多次发出“mvn clean install”,因为我需要在本地更新我的工件Maven 回购。根据上面人们所说,运行“安装”将导致集成测试阶段运行,从而导致我失去宝贵的开发时间。
  • 嗯...不确定“安装”运行集成测试。无论如何,我仍然会使用阶段而不是配置文件。配置文件最好用于支持不同的应用服务器等。
  • 我会继续玩这个。感谢您的建议!
  • @jorge 我想在这里使用的正确目标是验证,对吧?
【解决方案9】:

您可以按照maven documentation 与构建一起运行单元测试并单独运行集成测试。

<project>
    <properties>
        <skipTests>true</skipTests>
    </properties>
    [...]
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.20.1</version>
                <configuration>
                    <skipITs>${skipTests}</skipITs>
                </configuration>
            </plugin>
        </plugins>
    </build>
    [...]
</project>

这将允许您在默认禁用所有集成测试的情况下运行。要运行它们,请使用以下命令:

mvn install -DskipTests=false

【讨论】:

    【解决方案10】:

    我不需要执行其他答案中建议的所有设置,我可以单独运行单元测试或集成测试。

    我所做的是:

    1. 将下面的配置添加到 pom.xml 以指示 maven 集成测试文件(java 代码和资源文件)在哪里:
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>add-integration-test-source</id>
                    <phase>generate-test-sources</phase>
                    <goals>
                        <goal>add-test-source</goal>
                    </goals>
                    <configuration>
                        <sources>
                            <source>src/integration-test/java</source>
                        </sources>
                    </configuration>
                </execution>
                <execution>
                    <id>add-integration-test-resource</id>
                    <phase>generate-test-resources</phase>
                    <goals>
                        <goal>add-test-resource</goal>
                    </goals>
                    <configuration>
                        <resources>
                            <resource>
                                <directory>src/integration-test/resources</directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
    
    1. 使用“IT”后缀命名集成测试文件,例如“MyTestIT.java”

    2. 使用此命令仅执行集成测试:

      mvn failsafe:integration-test failsafe:verify

    在上面的命令中,“failsafe:integration-test”将执行 *IT.java 文件,“failsafe:verify”将告诉 maven 检查之前运行的任何集成测试是否失败。如果您不使用 'failsafe:verify',即使一项测试失败,mvn 命令也会成功退出。

    1. 要仅运行单元测试,请运行:

      mvn test

    【讨论】:

    • 如果我真的很生气,当像这种运行单元测试或集成测试的简单分离这样的基本功能在 Maven 中仍然不能可靠地工作时,我真的很生气吗?我真的想要太多了吗?
    猜你喜欢
    • 2017-09-14
    • 1970-01-01
    • 2014-03-12
    • 2017-09-25
    • 2012-05-05
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多