skip to content

What is the Maven Failsafe plugin and how does it differ from the Surefire plugin?

level: juniorimportance: must knowfreq 70%

answer

  1. Surefire = unit, Failsafe = IT
  2. fail-fast vs deferred-to-verify
  3. *Test vs *IT naming
  4. teardown must always run
  5. mvn verify not mvn test

basics

~10 s

Failsafe runs integration tests; Surefire runs unit tests. Surefire fails the build immediately on a test failure, while Failsafe defers failure so teardown always runs.

solid answer

~40 s

Surefire and Failsafe are sibling Maven test plugins. Surefire runs **unit tests** in the `test` phase and fails fast — a failed test aborts the build right there. Failsafe runs **integration tests** (slower, needing external resources) and is bound to two phases: `integration-test` actually runs the tests but does NOT fail the build, and `verify` checks the results and fails if anything broke. That two-step split is the whole point: it lets a `post-integration-test` teardown (stop a server, drop a DB, free a port) run even when tests failed, instead of leaking resources. They also use different default naming patterns: Surefire picks up `*Test`/`Test*`, Failsafe picks up `*IT`/`IT*`/`*ITCase`.

code

bash · 4 lines
bash
# Unit tests only stop at the test phase:
mvn test
# Integration tests need the verify phase so the verify goal can fail the build:
mvn verify

go deeper

for a junior

Knows Failsafe = integration tests, Surefire = unit tests, and run with mvn verify.

for a middle

Can explain the deferred-failure mechanism and the *IT vs *Test naming routing.

for a senior

Articulates why the split protects teardown and configures both goals correctly.

for a principal

Defines team conventions separating fast unit from slow IT runs and CI phase strategy.

## What these plugins are Maven runs tests through plugins bound to lifecycle phases. Two ship for testing: - **maven-surefire-plugin** — runs **unit tests**: small, fast, isolated tests with no external dependencies. - **maven-failsafe-plugin** — runs **integration tests**: tests that exercise multiple components together or need real infrastructure (a database, an embedded web server, a message broker). ## Why two plugins exist The core problem is **resource cleanup**. An integration test often starts something heavy before tests (e.g. a server) and must stop it after, even if tests fail. If the test runner aborted the build the instant a test failed (the way unit tests do), the teardown step would be skipped and you'd leak processes, ports, or containers. Failsafe solves this by splitting work across phases: - `pre-integration-test` — set up (start server / DB). - `integration-test` — Failsafe's **`integration-test` goal** runs the tests and records results to a summary file but **does not fail the build** here. - `post-integration-test` — tear down (always runs because the build hasn't failed yet). - `verify` — Failsafe's **`verify` goal** reads the summary and **fails the build** if any integration test failed. Surefire, by contrast, binds its single `test` goal to the `test` phase and **fails fast**: that's fine for unit tests because there's nothing to tear down. ## Naming conventions (how tests get routed) - Surefire default includes: `**/Test*.java`, `**/*Test.java`, `**/*Tests.java`, `**/*TestCase.java`. - Failsafe default includes: `**/IT*.java`, `**/*IT.java`, `**/*ITCase.java`. Naming a class `FooIT` routes it to Failsafe; `FooTest` routes it to Surefire. This keeps slow integration tests out of the fast unit-test run. ## Minimal setup Failsafe is NOT in the default lifecycle, so you must declare it and bind both goals: ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.2.5</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> ``` Run with `mvn verify` (not `mvn test`, which stops before integration tests).

  • Why does `mvn test` not run your integration tests?
    The `test` phase comes before `integration-test`/`verify`; Failsafe's goals bind to those later phases, so they never execute when you stop at `test`. Use `mvn verify`.
  • Can you change which classes Failsafe picks up?
    Yes, via `<includes>`/`<excludes>` in the plugin config, overriding the default `*IT` patterns.

Surefire is a smoke detector that cuts the power immediately; Failsafe is one that finishes the cooking, lets you turn off the stove, then tells you the food burned.

saying these in an interview costs you the question

  • Saying Failsafe and Surefire are interchangeable or do the same thing.
  • Claiming `mvn test` runs integration tests.
  • Thinking Failsafe fails the build during integration-test (it defers to verify).

context