Close

JUnit 5 - @RepeatedTest failureThreshold vs RepetitionInfo

[Last Updated: Dec 27, 2025]

In JUnit 5+, @RepeatedTest allows a test to be executed multiple times. Two related but fundamentally different APIs are often confused: failureThreshold() and RepetitionInfo#getFailureThreshold().

The key distinction is that failureThreshold() defines an execution policy enforced by the JUnit engine, whereas RepetitionInfo#getFailureThreshold() only exposes that policy to the test at runtime for inspection.

Example

package com.logicbig.example;

import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import static org.junit.jupiter.api.Assertions.fail;

public class RepeatedTestFailureThresholdTest {

    @RepeatedTest(value = 5, failureThreshold = 2)
    void repeatedTestWithFailureThreshold(RepetitionInfo repetitionInfo) {

        int current = repetitionInfo.getCurrentRepetition();
        int threshold = repetitionInfo.getFailureThreshold();

        System.out.println("repetition=" + current + ", failureThreshold=" + threshold);

        //simulate failure
        fail("intentional failure");
    }
}

Output

$ mvn test -Dtest=RepeatedTestFailureThresholdTest
[INFO] Scanning for projects...
[INFO]
[INFO] ---< com.logicbig.example:junit-5-repetition-Info-failure-threshold >---
[INFO] Building junit-5-repetition-Info-failure-threshold 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-repetition-Info-failure-threshold ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-repeated-tests\junit-5-repetition-Info-failure-threshold\src\main\resources
[INFO]
[INFO] --- compiler:3.14.1:compile (default-compile) @ junit-5-repetition-Info-failure-threshold ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-repetition-Info-failure-threshold ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-repeated-tests\junit-5-repetition-Info-failure-threshold\src\test\resources
[INFO]
[INFO] --- compiler:3.14.1:testCompile (default-testCompile) @ junit-5-repetition-Info-failure-threshold ---
[INFO] Nothing to compile - all classes are up to date.
[INFO]
[INFO] --- surefire:3.5.4:test (default-test) @ junit-5-repetition-Info-failure-threshold ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
repetition=1, failureThreshold=2
repetition=2, failureThreshold=2
[INFO] +--com.logicbig.example.RepeatedTestFailureThresholdTest - 0.145 ss
[INFO] | +-- [XX] repeatedTestWithFailureThreshold(RepetitionInfo) repetition 1 of 5 - 0.047 ss
[INFO] | +-- [XX] repeatedTestWithFailureThreshold(RepetitionInfo) repetition 2 of 5 - 0.015 ss
[INFO] | +-- [??] repeatedTestWithFailureThreshold(RepetitionInfo) repetition 3 of 5 (Failure threshold [2] exceeded) - 0 ss
[INFO] | +-- [??] repeatedTestWithFailureThreshold(RepetitionInfo) repetition 4 of 5 (Failure threshold [2] exceeded) - 0 ss
[INFO] | '-- [??] repeatedTestWithFailureThreshold(RepetitionInfo) repetition 5 of 5 (Failure threshold [2] exceeded) - 0 ss
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] RepeatedTestFailureThresholdTest.repeatedTestWithFailureThreshold:18 intentional failure
[ERROR] RepeatedTestFailureThresholdTest.repeatedTestWithFailureThreshold:18 intentional failure
[INFO]
[ERROR] Tests run: 5, Failures: 2, Errors: 0, Skipped: 3
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.092 s
[INFO] Finished at: 2025-12-27T15:15:07+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.4:test (default-test) on project junit-5-repetition-Info-failure-threshold: There are test failures.
[ERROR]
[ERROR] See D:\example-projects\junit-5\junit-5-repeated-tests\junit-5-repetition-Info-failure-threshold\target\surefire-reports for the individual test results.
[ERROR] See dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

In this example, the test is configured to run five times with a failure threshold of two. The test intentionally fails on specific repetitions to demonstrate how the threshold is enforced by the engine.

Inside the test method, RepetitionInfo is injected to read the configured failure threshold. This information is used only for logging and does not influence whether further repetitions are executed.

The output confirms that once the failure count reaches the configured threshold, JUnit stops executing the remaining repetitions automatically. The presence of getFailureThreshold() simply provides visibility into this rule and does not control execution flow.

Adaptive Diagnostic Logging Example

In this example, we use the threshold to decide whether to perform an expensive "Heap Dump" or "Thread Dump" when a specific repetition fails.

package com.logicbig.example;

import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;

class DiagnosticRepeatedTest {

    @RepeatedTest(value = 5, failureThreshold = 2)
    void resilientIntegrationTest(RepetitionInfo info) {
        try {
            // Your actual business logic/integration call
            runComplexIntegration();

        } catch (Exception e) {
            // APPLICATION LOGIC based on the threshold
            // If the threshold is > 1, we are in "investigation mode"
            if (info.getFailureThreshold() > 1) {
                performExpensiveDiagnostic(e);
            }

            throw e; // Still fail the test so JUnit can track the threshold
        }
    }

    private void runComplexIntegration() {
        //simulate failure
        fail("Network Glitch");
    }

    private void performExpensiveDiagnostic(Exception e) {
        System.err.println("Threshold is high: capturing full stack trace and system state...");
    }
}

Output

$ mvn test -Dtest=DiagnosticRepeatedTest
[INFO] Scanning for projects...
[INFO]
[INFO] ---< com.logicbig.example:junit-5-repetition-Info-failure-threshold >---
[INFO] Building junit-5-repetition-Info-failure-threshold 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-repetition-Info-failure-threshold ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-repeated-tests\junit-5-repetition-Info-failure-threshold\src\main\resources
[INFO]
[INFO] --- compiler:3.14.1:compile (default-compile) @ junit-5-repetition-Info-failure-threshold ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-repetition-Info-failure-threshold ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-repeated-tests\junit-5-repetition-Info-failure-threshold\src\test\resources
[INFO]
[INFO] --- compiler:3.14.1:testCompile (default-testCompile) @ junit-5-repetition-Info-failure-threshold ---
[INFO] Recompiling the module because of changed source code.
[INFO] Compiling 2 source files with javac [debug target 25] to target\test-classes
[INFO]
[INFO] --- surefire:3.5.4:test (default-test) @ junit-5-repetition-Info-failure-threshold ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] +--com.logicbig.example.DiagnosticRepeatedTest - 0.098 ss
[INFO] | +-- [XX] resilientIntegrationTest(RepetitionInfo) repetition 1 of 5 - 0.033 ss
[INFO] | +-- [XX] resilientIntegrationTest(RepetitionInfo) repetition 2 of 5 - 0.009 ss
[INFO] | +-- [??] resilientIntegrationTest(RepetitionInfo) repetition 3 of 5 (Failure threshold [2] exceeded) - 0 ss
[INFO] | +-- [??] resilientIntegrationTest(RepetitionInfo) repetition 4 of 5 (Failure threshold [2] exceeded) - 0 ss
[INFO] | '-- [??] resilientIntegrationTest(RepetitionInfo) repetition 5 of 5 (Failure threshold [2] exceeded) - 0 ss
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] DiagnosticRepeatedTest.resilientIntegrationTest:12->runComplexIntegration:27 Network Glitch
[ERROR] DiagnosticRepeatedTest.resilientIntegrationTest:12->runComplexIntegration:27 Network Glitch
[INFO]
[ERROR] Tests run: 5, Failures: 2, Errors: 0, Skipped: 3
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.757 s
[INFO] Finished at: 2025-12-27T15:12:30+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.4:test (default-test) on project junit-5-repetition-Info-failure-threshold: There are test failures.
[ERROR]
[ERROR] See D:\example-projects\junit-5\junit-5-repeated-tests\junit-5-repetition-Info-failure-threshold\target\surefire-reports for the individual test results.
[ERROR] See dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

The output confirms that failureThreshold acts as a circuit breaker while RepetitionInfo acts as a metadata reader. By setting failureThreshold = 2, JUnit automatically aborted the suite after the second error, resulting in Skipped: 3. Simultaneously, your code used info.getFailureThreshold() to programmatically detect this limit and trigger performExpensiveDiagnostic(), showing that the annotation controls the test lifecycle while the interface enables adaptive test logic.

Example Project

Dependencies and Technologies Used:

  • junit-jupiter-engine 6.0.1 (Module "junit-jupiter-engine" of JUnit)
     Version Compatibility: 5.10.0 - 6.0.1Version List
    ×

    Version compatibilities of junit-jupiter-engine with this example:

    • 5.10.0
    • 5.10.1
    • 5.10.2
    • 5.10.3
    • 5.10.4
    • 5.10.5
    • 5.11.0
    • 5.11.1
    • 5.11.2
    • 5.11.3
    • 5.11.4
    • 5.12.0
    • 5.12.1
    • 5.12.2
    • 5.13.0
    • 5.13.1
    • 5.13.2
    • 5.13.3
    • 5.13.4
    • 5.14.0
    • 5.14.1
    • 6.0.0
    • 6.0.1

    Versions in green have been tested.

  • JDK 25
  • Maven 3.9.11

JUnit 5 - RepeatedTest failureThreshold vs RepetitionInfo Select All Download
  • junit-5-repetition-Info-failure-threshold
    • src
      • test
        • java
          • com
            • logicbig
              • example
                • RepeatedTestFailureThresholdTest.java

    See Also