Skip to content

Maven Surefire Test Execution Error Fix

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about Maven Surefire Test Execution Error Fix. We cover key concepts, practical examples, and best practices.

Your Maven build fails with Tests run: X, Failures: Y, Errors: Z, No tests found, or java.lang.NoClassDefFoundError in test phase — the Surefire plugin is misconfigured, test framework is incompatible, or test classes are not being discovered.

Step-by-Step Fix

1. Check Surefire plugin configuration

<!-- Wrong: no Surefire configuration, uses default settings -->
<project>
  <build>
    <plugins>
      <!-- Missing Surefire plugin -->
    </plugins>
  </build>
</project>

<!-- Right: configure Surefire with JUnit 5 -->
<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.2.5</version>
        <configuration>
          <includes>
            <include>**/*Test.java</include>
            <include>**/*Tests.java</include>
            <include>**/*TestCase.java</include>
          </includes>
          <excludes>
            <exclude>**/Abstract*.java</exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

2. Fix JUnit version mismatch

<!-- Wrong: mixing JUnit 4 and 5 dependencies -->
<project>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.10.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

<!-- Right: use JUnit 5 with the full engine dependency -->
<project>
  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.10.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

<!-- Or for JUnit 4 only -->
<project>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

3. Add the Vintage engine for JUnit 4 tests

<!-- If you have JUnit 4 tests but want to use JUnit 5 platform -->
<project>
  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.10.1</version>
      <scope>test</scope>
    </dependency>
    <!-- JUnit 4 tests need the Vintage engine -->
    <dependency>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
      <version>5.10.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

4. Fix test isolation and forking

<!-- Wrong: all tests run in the same JVM (state leakage) -->
<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <forkCount>0</forkCount>  <!-- No forking -->
  </configuration>
</plugin>

<!-- Right: fork for each test class to ensure isolation -->
<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <forkCount>1</forkCount>  <!-- One JVM per test class -->
    <reuseForks>true</reuseForks>
    <argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
  </configuration>
</plugin>

5. Add test output to build logs

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <!-- Show test output inline -->
    <redirectTestOutputToFile>false</redirectTestOutputToFile>
    <printSummary>true</printSummary>
    <reportFormat>plain</reportFormat>
    <trimStackTrace>false</trimStackTrace>
  </configuration>
</plugin>

6. Run a single test class

# Run a specific test class
mvn test -Dtest=com.myapp.service.UserServiceTest

# Run a specific test method
mvn test -Dtest=com.myapp.service.UserServiceTest#testLogin

# Run tests matching a pattern
mvn test -Dtest="*ServiceTest"

# Skip tests for a quick compilation check
mvn install -DskipTests

7. Fix NoClassDefFoundError in tests

<!-- Wrong: test depends on classes not in the test classpath -->
<project>
  <dependencies>
    <!-- Missing test-scoped dependency -->
  </dependencies>
</project>

<!-- Right: ensure all test dependencies are correctly scoped -->
<project>
  <dependencies>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>5.8.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>3.24.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Prevention

  • Use the latest maven-surefire-plugin version (3.x) with JUnit 5.
  • Run mvn test -Dtest="*Test" to verify test discovery before running all tests.
  • Use forkCount=1 to isolate tests and prevent state leakage.
  • Review the target/surefire-reports/ directory for detailed test reports.
  • Add the Vintage engine if migrating from JUnit 4 to 5.

Common Mistakes with surefire error

  1. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  2. Using head and tail instead of pattern matching, causing runtime errors on empty lists
  3. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks

These mistakes appear frequently in real-world MAVEN code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

Why does Surefire report "No tests found"?

Your test classes don't match the default includes (**/*Test.java, **/*Tests.java). Rename your tests or update the Surefire <includes> configuration. Verify the test class name ends with "Test". |||What is the difference between JUnit 4 and JUnit 5? JUnit 5 has a modular architecture (junit-jupiter-api, junit-jupiter-engine), supports Java 8+ features, and has better extension points. JUnit 4 is older but still widely used. |||How do I debug a failing test that passes in my IDE? Tests may pass in the IDE (which uses a specific classpath) but fail in Maven (which uses the full dependency tree). Run mvn test -Dtest=YourTest -e for detailed error output.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro