Difference Between Maven Surefire and Failsafe Plugins – Maven Surefire和Failsafe插件的区别

最后修改: 2021年 7月 2日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In typical Test Driven Development, we aim to write lots of low-level unit tests that are fast to run and set up in isolation. Additionally, there are also few high-level integration tests that are dependent on external systems, for example, setting up a server or databases. Unsurprisingly, these are typically both resource and time-consuming.

在典型的测试驱动开发中,我们的目标是编写大量的低级单元测试,这些测试可以快速运行,并在隔离状态下设置。此外,还有一些依赖于外部系统的高级集成测试,例如,设置服务器或数据库。不出所料,这些通常既耗费资源又耗费时间。

Hence, these tests mostly require some pre-integration setup and post-integration cleanup for the graceful termination. Therefore, it’s desirable to distinguish between the two types of tests and be able to run them separately during the build process.

因此,这些测试大多需要一些整合前的设置和整合后的清理,以实现优雅的终止。 因此,最好能区分这两种类型的测试,并能在构建过程中分别运行它们。

In this tutorial, we’ll compare the Surefire and Failsafe plugins most commonly used for running various types of tests in a typical Apache Maven build.

在本教程中,我们将比较在典型的Apache Maven构建中最常用于运行各类测试的Surefire和Failsafe插件。

2. Surefire Plugin

2.万无一失的插件

The Surefire Plugin belongs to a set of Maven core plugins and runs the unit tests of the application.

Surefire插件属于一组Maven core插件,运行应用程序的单元测试。

The project POM includes this plugin by default, but we can also configure it explicitly:

项目POM默认包括这个插件,但我们也可以明确配置它。

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                ....
            </plugin>
         </plugins>
    </pluginManagement>
</build>

The plugin binds to the test phase of the default lifecycle. Therefore, let’s execute it with the command:

该插件与默认生命周期的test阶段绑定。因此,让我们用命令来执行它。

mvn clean test

This runs all the unit tests in our project. Since the Surefire plugin binds with the test phase, in case of any test failures, the build fails, and no further phases execute during the build process.

这将运行我们项目中的所有单元测试。由于Surefire插件与test阶段绑定,在任何测试失败的情况下,构建失败,并且在构建过程中没有其他阶段执行

Alternatively, we can modify the plugin configuration to run integration tests, as well as the unit tests. However, this may not be desirable behavior for integration tests which could require some environment setup before, as well as some clean-up after test execution.

另外,我们可以修改插件配置来运行集成测试,以及单元测试。然而,对于集成测试来说,这可能不是理想的行为,因为它可能需要在测试之前进行一些环境设置,以及在测试执行之后进行一些清理。

Maven provides another plugin precisely for this purpose.

Maven提供的另一个插件正是为了这个目的。

3. Failsafe Plugin

3.故障安全插件

The Failsafe Plugin is designed to run the integration tests in the project.

Failafe Plugin是为了在项目中运行集成测试。

3.1. Configuration

3.1 配置

First, let’s configure this in the project POM:

首先,让我们在项目的POM中进行配置。

<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>3.0.0-M5</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            ....
        </execution>
    </executions>
</plugin>

Here, the plugin’s goals bind to the integration-test and verify phases of the build cycle in order to execute the integration tests.

这里,插件的目标与构建周期的集成测试验证阶段绑定,以执行集成测试。

Now, let’s execute the verify phase from the command line:

现在,让我们从命令行执行验证阶段。

mvn clean verify

This runs all the integration tests, but if any tests fail during the integration-test phase, the plugin does not fail the build immediately.

这将运行所有的集成测试,但如果任何测试在集成测试阶段失败,该插件不会立即失败构建

Instead, Maven still executes the post-integration-test phase. Therefore we can still perform any cleanup and environment tear-down as part of the post-integration-test phase. The subsequent verify phase of the build process reports any test failures.

相反,Maven仍然执行post-integration-test阶段。因此,我们仍然可以在post-integration-test阶段执行任何清理和环境拆分。构建过程的后续verify阶段会报告任何测试失败。

3.2. Example

3.2.例子

In our example, we’ll configure a Jetty server to start prior to running the integration tests and stop after the test execution.

在我们的例子中,我们将配置一个Jetty服务器,在运行集成测试之前启动,在测试执行之后停止。

First, let’s add the Jetty Plugin to our POM:

首先,让我们把Jetty插件添加到我们的POM中。

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.4.11.v20180605</version>
    ....
    <executions>
        <execution>
            <id>start-jetty</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start</goal>
            </goals>
        </execution>
        <execution>
            <id>stop-jetty</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Here we’ve added the configuration to start and stop the Jetty server during the pre-integration-test and post-integration-test phases respectively.

这里我们添加了配置,以便在整合前测试整合后测试阶段分别启动和停止Jetty服务器。

Now, let’s execute our integration tests once again and see the console output:

现在,让我们再一次执行我们的集成测试,看看控制台的输出。

....
[INFO] <<< jetty-maven-plugin:9.4.11.v20180605:start (start-jetty) 
  < validate @ maven-integration-test <<<
[INFO] --- jetty-maven-plugin:9.4.11.v20180605:start (start-jetty)
  @ maven-integration-test ---
[INFO] Started ServerConnector@4b9dc62f{HTTP/1.1,[http/1.1]}{0.0.0.0:8999}
[INFO] Started @6794ms
[INFO] Started Jetty Server
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:integration-test (default)
  @ maven-integration-test ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.024 s
  <<< FAILURE! - in com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest
[ERROR] com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest.whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted
  Time elapsed: 0.012 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest
          .whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted(FailsafeBuildPhaseIntegrationTest.java:11)
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR]   FailsafeBuildPhaseIntegrationTest.whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted:11
  expected: <true> but was: <false>
[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO]
[INFO] --- jetty-maven-plugin:9.4.11.v20180605:stop (stop-jetty)
  @ maven-integration-test ---
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:verify (default)
  @ maven-integration-test ---
[INFO] Stopped ServerConnector@4b9dc62f{HTTP/1.1,[http/1.1]}{0.0.0.0:8999}
[INFO] node0 Stopped scavenging
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
....

Here, as per our configuration, the Jetty server starts prior to the integration test execution. For demonstration, we have a failing integration test, but this does not fail the build immediately. The post-integration-test phase executes after the test execution, and the server stops before build failure.

在这里,按照我们的配置,Jetty服务器在集成测试执行之前启动。为了演示,我们有一个失败的集成测试,但这并不会立即导致构建失败。后集成测试阶段在测试执行后执行,服务器在构建失败前停止。

In contrast, if we use Surefire Plugin to run these integration tests, the build would have stopped at the integration-test phase without performing any required cleanup.

相比之下,如果我们使用Surefire Plugin来运行这些集成测试,构建会在集成测试阶段停止,而不执行任何需要的清理

An additional benefit of using different plugins for different types of tests is the separation between the various configurations. This improves the maintainability of the project build.

对不同类型的测试使用不同的插件的另一个好处是各种配置之间的分离。这提高了项目构建的可维护性。

4. Conclusion

4.总结

In this article, we compared Surefire and Failsafe plugins for separating and running different types of tests. We also looked at an example and saw how Failsafe Plugin provides additional functionality for running tests that require further setup and cleanup.

在这篇文章中,我们比较了Surefire和Failsafe插件对不同类型测试的分离和运行。我们还看了一个例子,看到Failsafe插件如何为运行需要进一步设置和清理的测试提供额外功能。

As always, the code is available over on GitHub.

像往常一样,代码可在GitHub上获得