Close

JUnit 5 - Introduction to Test Ordering

[Last Updated: Dec 22, 2025]

JUnit 5 introduces explicit control over test execution order through annotations and configuration. Unlike JUnit 4 where test order was essentially undefined and non-deterministic, JUnit 5 provides reliable mechanisms to define both method and class execution sequences.

Default Test Execution Order

By default, JUnit 5 does not provide any specific execution order for test methods or test classes. This intentional design encourages writing independent, stateless tests. However, there are scenarios where controlled ordering is necessary, such as integration tests with setup dependencies or performance tests that need specific sequences.

By default, test classes and methods will be ordered using an algorithm that is deterministic but intentionally nonobvious. This ensures that subsequent runs of a test suite execute test classes and test methods in the same order, thereby allowing for repeatable builds.

JUnit 5 vs JUnit 4 Approach

JUnit 4 relied on implementation details of the JVM or used workarounds like method name sorting. JUnit 5 provides explicit, configurable ordering through standardized annotations and interfaces, making test order predictable and maintainable.

Key Ordering Components

  • @TestMethodOrder: Annotation to specify method ordering strategy for a test class
  • @TestClassOrder: Annotation to specify class ordering strategy for test suites
  • @Order: Annotation to assign numerical order values to test methods or classes
  • MethodOrderer: Interface for implementing custom method ordering logic.
    Also implemented by built-in method ordering strategies:
    1. MethodOrderer.Default
    2. MethodOrderer.MethodName
    3. MethodOrderer.DisplayName
    4. MethodOrderer.OrderAnnotation
    5. MethodOrderer.Random
  • ClassOrderer: Interface for implementing custom class ordering strategies
    Also implemented by built-in class ordering strategies:
    1. ClassOrderer.Default
    2. ClassOrderer.ClassName
    3. ClassOrderer.DisplayName
    4. ClassOrderer.OrderAnnotation
    5. ClassOrderer.Random

    @TestClassOrder is primarily designed to order @Nested test classes within a single test class or to set a global ordering policy for the platform.

Java source and doc

Definition of TestMethodOrder

Version: 6.0.0
Since : 5.4.0
 package org.junit.jupiter.api;
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Inherited
 @API(status = STABLE, since = "5.7")
 public @interface TestMethodOrder {
     Class<? extends MethodOrderer> value(); 1
 }
1The MethodOrderer to use.

It can only be used on class level.

Definition of TestClassOrder

Version: 6.0.0
Since : 5.8.0
 package org.junit.jupiter.api;
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Inherited
 @API(status = STABLE, since = "5.10")
 public @interface TestClassOrder {
     Class<? extends ClassOrderer> value(); 1
 }
1The ClassOrderer to use.

It can only be used on class level.

Definition of Order

Version: 6.0.0
Since : 5.4.0
 package org.junit.jupiter.api;
 @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @API(status = STABLE, since = "5.9")
 public @interface Order {
     int value(); 1
 }
1The order value for the annotated element (i.e., field, method, or class).

We must annotate our test class with @TestMethodOrder(MethodOrderer.OrderAnnotation.class) to enable ordering based on the @Order values.

Elements are ordered based on priority where a lower value has greater priority than a higher value. For example, Integer.MAX_VALUE has the lowest priority.

Definition of MethodOrderer

Version: 6.0.0
Since : 5.4.0
 package org.junit.jupiter.api;
 @API(status = STABLE, since = "5.7")
 public interface MethodOrderer {
     void orderMethods(MethodOrdererContext context); 1
     default Optional<ExecutionMode> getDefaultExecutionMode() { 2
         ...
     }
     @API(status = EXPERIMENTAL, since = "6.0")
     final class Default implements MethodOrderer { 3
         ...
     }
     @API(status = STABLE, since = "5.10")
     class MethodName implements MethodOrderer { 4
         ...
     }
     @API(status = STABLE, since = "5.10")
     class DisplayName implements MethodOrderer { 5
         ...
     }
     class OrderAnnotation implements MethodOrderer { 6
         ...
     }
     class Random implements MethodOrderer { 7
         ...
     }
 }
1Order the methods encapsulated in the supplied MethodOrdererContext.
2Get the default ExecutionMode for the test class
3MethodOrderer that allows to explicitly specify that the default (Since 6.0)
4MethodOrderer that sorts methods alphanumerically based on their (Since 5.7)
5MethodOrderer that sorts methods alphanumerically based on their (Since 5.7)
6MethodOrderer that sorts methods based on the @Order
7MethodOrderer that orders methods pseudo-randomly.

Definition of ClassOrderer

Version: 6.0.0
Since : 5.8.0
 package org.junit.jupiter.api;
 @API(status = STABLE, since = "5.10")
 public interface ClassOrderer {
     void orderClasses(ClassOrdererContext context); 1
     @API(status = EXPERIMENTAL, since = "6.0")
     final class Default implements ClassOrderer { 2
         ...
     }
     class ClassName implements ClassOrderer { 3
         ...
     }
     class DisplayName implements ClassOrderer { 4
         ...
     }
     class OrderAnnotation implements ClassOrderer { 5
         ...
     }
     class Random implements ClassOrderer { 6
         ...
     }
 }
1Order the classes encapsulated in the supplied ClassOrdererContext.
2ClassOrderer that allows to explicitly specify that the default (Since 6.0)
3ClassOrderer that sorts classes alphanumerically based on their
4ClassOrderer that sorts classes alphanumerically based on their
5ClassOrderer that sorts classes based on the @Order
6ClassOrderer that orders classes pseudo-randomly.

In next tutorials we will see the examples related to JUnit test execution order.

See Also