Close

JUnit 5 - @RepeatedTest with RepetitionInfo

[Last Updated: Dec 27, 2025]

JUnit allows additional context to be injected into a repeated test method using RepetitionInfo. This enables the test logic to be aware of the current repetition information.

Definition of RepetitionInfo

Version: 6.0.0
 package org.junit.jupiter.api;
 @API(status = STABLE, since = "5.0")
 public interface RepetitionInfo {
     int getCurrentRepetition(); 1
     int getTotalRepetitions(); 2
     @API(status = MAINTAINED, since = "5.13.3")
     int getFailureCount(); 3
     @API(status = MAINTAINED, since = "5.13.3")
     int getFailureThreshold(); 4
 }
1Get the current repetition of the corresponding @RepeatedTest method.
2Get the total number of repetitions of the corresponding @RepeatedTest method.
3Get the current number of repetitions of the corresponding @RepeatedTest method that have ended in a failure. (Since 5.10)
4Get the configured failure threshold of the corresponding @RepeatedTest method. (Since 5.10)

In this tutorial we will focus on getCurrentRepetition() and getTotalRepetitions() methods only.

Common Usage

While it’s easy to think of RepetitionInfo as just a way to label your console logs (e.g., "Running test 3 of 10"), its real power lies in controlling the logic and data of your test dynamically based on which iteration is currently running.

  1. Indexing Data: Use repetitionInfo.getCurrentRepetition() to pick a specific element from a collection or array, allowing you to iterate through different data sets manually.
  2. Stateful Testing: Change assertions based on the iteration count, such as expecting success for the first few runs and a "Rate Limit" error once getCurrentRepetition() exceeds a certain threshold.
  3. Progressive Stress: Increase the workload or complexity in each cycle by using the repetition number as a multiplier for the amount of data processed.
  4. Final Run Logic: Compare getCurrentRepetition() with repetitionInfo.getTotalRepetitions() to trigger a specific final validation or resource cleanup only during the very last execution.

Comparison with @ParameterizedTest: While @ParameterizedTest is designed for injecting specific data sets into separate test runs, RepetitionInfo is used within a @RepeatedTest to dynamically alter logic, load, or assertions based on the current progress of the loop.

Example

Quick example how to use @RepetitionInfo

package com.logicbig.example;

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

public class RepeatedTestWithRepetitionInfoExample {

    @RepeatedTest(3)
    void myTest(RepetitionInfo repetitionInfo) {
        System.out.println("current repetition: " +
                                   repetitionInfo.getCurrentRepetition());
        System.out.println("total repetitions: " +
                                   repetitionInfo.getTotalRepetitions());
        System.out.println("failure count: " +
                                   repetitionInfo.getFailureCount());
        System.out.println("failure threshold " +
                                   repetitionInfo.getFailureThreshold());
        assertTrue(true);
    }
}

Output

$ mvn test -Dtest=RepeatedTestWithRepetitionInfoExample
[INFO] Scanning for projects...
[INFO]
[INFO] --< com.logicbig.example:junit-5-repeated-test-with-repetition-info >---
[INFO] Building junit-5-repeated-test-with-repetition-info 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-repeated-test-with-repetition-info ---
[WARNING] Using platform encoding (Cp1252 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-repeated-test-with-repetition-info\src\main\resources
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ junit-5-repeated-test-with-repetition-info ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-repeated-test-with-repetition-info ---
[WARNING] Using platform encoding (Cp1252 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-repeated-test-with-repetition-info\src\test\resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ junit-5-repeated-test-with-repetition-info ---
[INFO] Changes detected - recompiling the module! :source
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 1 source file with javac [debug target 17] to target\test-classes
[INFO]
[INFO] --- surefire:3.5.0:test (default-test) @ junit-5-repeated-test-with-repetition-info ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] +--com.logicbig.example.RepeatedTestWithRepetitionInfoExample - 0.309 ss
[INFO] | +-- [OK] myTest(RepetitionInfo) repetition 1 of 3 - 0.104 ss
[INFO] | +-- [OK] myTest(RepetitionInfo) repetition 2 of 3 - 0.014 ss
[INFO] | '-- [OK] myTest(RepetitionInfo) repetition 3 of 3 - 0.003 ss
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.412 s
[INFO] Finished at: 2025-12-26T13:38:57+08:00
[INFO] ------------------------------------------------------------------------

The output of this example confirms that each execution receives accurate repetition metadata. The test verifies that the current repetition number never exceeds the total number of repetitions. This demonstrates how RepetitionInfo can be used to implement repetition-aware assertions while keeping the test logic minimal and readable.

Another Example, Conditional Assertions using RepetitionInfo

package com.logicbig.example;

import org.junit.jupiter.api.*;
import java.util.ArrayDeque;
import java.util.NoSuchElementException;
import java.util.Queue;

class QueueTest {

    // Shared state for the repetitions
    static Queue<String> queue = new ArrayDeque<>();

    @BeforeAll
    static void setup() {
        queue.add("Task 1");
        queue.add("Task 2");
        queue.add("Task 3");
    }

    @RepeatedTest(5)
    void testQueueDepletion(RepetitionInfo repetitionInfo) {
        if (repetitionInfo.getCurrentRepetition() <= 3) {
            // First 3 runs: Queue has items
            System.out.println("success test");
            Assertions.assertDoesNotThrow(() -> queue.remove(),
                "Should not fail on repetition " + repetitionInfo.getCurrentRepetition());
        } else {
            // 4th/5th run: Queue is empty, remove() throws NoSuchElementException
            System.out.println("failure test");
            Assertions.assertThrows(NoSuchElementException.class, () -> queue.remove(),
                "Should throw error on repetition " + repetitionInfo.getCurrentRepetition());
        }
    }
}

Output

$ mvn test -Dtest=QueueTest
[INFO] Scanning for projects...
[INFO]
[INFO] --< com.logicbig.example:junit-5-repeated-test-with-repetition-info >---
[INFO] Building junit-5-repeated-test-with-repetition-info 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-repeated-test-with-repetition-info ---
[WARNING] Using platform encoding (Cp1252 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-repeated-test-with-repetition-info\src\main\resources
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ junit-5-repeated-test-with-repetition-info ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-repeated-test-with-repetition-info ---
[WARNING] Using platform encoding (Cp1252 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-repeated-test-with-repetition-info\src\test\resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ junit-5-repeated-test-with-repetition-info ---
[INFO] Changes detected - recompiling the module! :input tree
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 2 source files with javac [debug target 17] to target\test-classes
[INFO]
[INFO] --- surefire:3.5.0:test (default-test) @ junit-5-repeated-test-with-repetition-info ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
success test
success test
success test
failure test
failure test
[INFO] +--com.logicbig.example.QueueTest - 0.106 ss
[INFO] | +-- [OK] testQueueDepletion(RepetitionInfo) repetition 1 of 5 - 0.030 ss
[INFO] | +-- [OK] testQueueDepletion(RepetitionInfo) repetition 2 of 5 - 0.001 ss
[INFO] | +-- [OK] testQueueDepletion(RepetitionInfo) repetition 3 of 5 - 0.001 ss
[INFO] | +-- [OK] testQueueDepletion(RepetitionInfo) repetition 4 of 5 - 0.005 ss
[INFO] | '-- [OK] testQueueDepletion(RepetitionInfo) repetition 5 of 5 - 0.001 ss
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.053 s
[INFO] Finished at: 2025-12-26T15:06:54+08:00
[INFO] ------------------------------------------------------------------------

The output confirms that RepetitionInfo enables state-aware testing by synchronizing assertions with the changing state of the queue. By switching from "success" to "failure" logic at the exact moment the queue is exhausted, it proves that the tool's practical value lies in managing temporal logic across multiple iterations of a single test method.

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 with RepetitionInfo Select All Download
  • junit-5-repeated-test-with-repetition-info
    • src
      • test
        • java
          • com
            • logicbig
              • example
                • RepeatedTestWithRepetitionInfoExample.java

    See Also