ChatGPT解决这个技术问题 Extra ChatGPT

如何让我的 Maven 集成测试运行

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

mvn test

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

mvn test -Dtest=**/*Integration

Integration.java 测试均未在子模块中执行。

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

Kief 的回答应该是公认的,因为它是在 Maven 中定义集成测试的当前标准。

K
Kief

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 中对其进行了描述。可以覆盖默认值很好,但如果他们能早点提到默认值就更好了。
O
Olathe

您可以设置 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 构建,我需要同时运行 *Test .java 和 *Integration.java。我必须执行 mvn install 然后 cd 到每个子目录并执行 mvn -Dtest=**/*Integration test
您应该使用故障安全插件进行集成测试,而不是万无一失的插件。在后期集成阶段完成之前,它不会使构建失败;允许您在构建失败之前拆除测试资源(例如 Web 服务器)。因此,故障安全。
对我来说,作为预集成阶段的一部分,码头服务器启动。最后的日志行是:[INFO] Started Jetty Server。之后,什么也没有发生。它卡住了。 maven surefire 故障安全插件不会执行测试,也不会停止码头服务器。知道有什么问题吗?我正在使用您指定的相同配置。
这个答案非常过时,应该更新或删除。
这个有什么帮助吗? stackoverflow.com/questions/48639730/…
J
Joshua Taylor

我已经完成了你想做的事情,而且效果很好。单元测试“*Tests”始终运行,而“*IntegrationTests”仅在您执行 mvn verify 或 mvn install 时运行。这是我的 POM 中的片段。 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
J
Jacob van Lingen

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

定义标记接口

public interface IntegrationTest {}

标记您的测试课程

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

import org.junit.experimental.categories.Category;

@Category(IntegrationTest.class)
public class ExampleIntegrationTest{

    @Test
    public void longRunningServiceTest() throws Exception {
    }

}

配置 Maven 单元测试

<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 配置,你不能这样做吗?
L
Liquidpie

您应该使用 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 版开始,已删除 <skipTests> 选项。现在,我们需要使用 -DskipITs 跳过集成测试,-DskipTests 跳过所有测试,mvn integration-test 只运行它(无单元测试)。
J
James Kingsbery

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


+1 这是我用的。运行良好,并允许您进行前/后设置,例如启动和关闭本地 servlet 容器。
maven-failsafe-plugin 已前往 Plugin Graveyard
墓地页面只是说 failsafe 插件已移至 maven-failsafe-plugin。看起来 maven-failsafe-plugin 仍处于活动状态(文档上次推送时间为 2014 年 3 月)。
D
Dov Benyomin Sohacheski

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

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

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

Inclusions and Exclusions of Tests

默认情况下,Surefire 插件将自动包含所有具有以下通配符模式的测试类: \*\*/Test\*.java - 包括其所有子目录和所有以“Test”开头的 java 文件名。 \*\*/\*Test.java - 包括其所有子目录和所有以“Test”结尾的 java 文件名。 \*\*/\*TestCase.java - 包括其所有子目录和所有以“TestCase”结尾的 java 文件名。如果测试类不符合命名约定,则配置 Surefire 插件并指定要包含的测试。


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

使用 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 我想在这里使用的正确目标是验证,对吗?
D
Dherik

您可以按照 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

B
Bruno Negrão Zica

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

我所做的是:

将下面的配置添加到 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>

使用“IT”后缀命名集成测试文件,例如“MyTestIT.java” 使用以下命令仅执行集成测试:mvn failsafe:integration-test failsafe:verify

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

要仅运行单元测试,请运行: mvn test


如果像这种运行单元测试或集成测试的简单分离这样的基本功能在 Maven 中仍然不能可靠地工作,我真的很生气吗?我真的想要太多吗?