When built-in ordering strategies don't meet your needs, JUnit 5 allows you to create custom MethodOrderer implementations. This enables specialized ordering logic, for example by evaluating custom annotations, method characteristics, or external configuration.
Implementing MethodOrderer
To create a custom MethodOrderer, implement the MethodOrderer interface and override the orderMethods method. This method receives a MethodOrdererContext containing test method information.
MethodOrderer interface
package org.junit.jupiter.api;
.....
public interface MethodOrderer {
void orderMethods(MethodOrdererContext context);
...
}
Definition of MethodOrdererContextVersion: 6.0.0 package org.junit.jupiter.api;
@API(status = STABLE, since = "5.7")
public interface MethodOrdererContext {
Class<?> getTestClass(); 1
List<? extends MethodDescriptor> getMethodDescriptors(); 2
Optional<String> getConfigurationParameter(String key); 3
}
Example
In this example, ReverseNameMethodOrderer orders test methods in reverse alphabetical order based on their names. The CustomMethodOrdererTest class uses this custom orderer to demonstrate the ordering effect.
package com.logicbig.example;
import org.junit.jupiter.api.MethodDescriptor;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.MethodOrdererContext;
import java.util.Comparator;
public class ReverseNameMethodOrderer implements MethodOrderer {
@Override
public void orderMethods(MethodOrdererContext context) {
Comparator<MethodDescriptor> comparator = Comparator.comparing(
(MethodDescriptor o) -> o.getMethod()
.getName());
context.getMethodDescriptors()
.sort(comparator.reversed());
}
}
Test class using the custom orderer
package com.logicbig.example;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(ReverseNameMethodOrderer.class)
class CustomMethodOrdererTest {
@Test
void testA() {
System.out.println("testA");
}
@Test
void testC() {
System.out.println("testC");
}
@Test
void testB() {
System.out.println("testB");
}
}
Output$ mvn test -Dtest=CustomMethodOrdererTest [INFO] Scanning for projects... [INFO] [INFO] --< com.logicbig.example:junit-5-custom-method-orderer-implementation >-- [INFO] Building junit-5-custom-method-orderer-implementation 1.0-SNAPSHOT [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-custom-method-orderer-implementation --- [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-ordering\junit-5-custom-method-orderer-implementation\src\main\resources [INFO] [INFO] --- compiler:3.11.0:compile (default-compile) @ junit-5-custom-method-orderer-implementation --- [INFO] No sources to compile [INFO] [INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-custom-method-orderer-implementation --- [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-ordering\junit-5-custom-method-orderer-implementation\src\test\resources [INFO] [INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ junit-5-custom-method-orderer-implementation --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- surefire:3.5.0:test (default-test) @ junit-5-custom-method-orderer-implementation --- [INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- testC testB testA [INFO] +--com.logicbig.example.CustomMethodOrdererTest - 0.090 ss [INFO] | +-- [OK] testC - 0.049 ss [INFO] | +-- [OK] testB - 0.008 ss [INFO] | '-- [OK] testA - 0.001 ss [INFO] [INFO] Results: [INFO] [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.194 s [INFO] Finished at: 2025-12-22T16:39:54+08:00 [INFO] ------------------------------------------------------------------------
As seen above the custom method orderer explicitly sorts test methods in reverse order before execution. As a result, JUnit invokes the methods starting from the last declared or highest-ranked method and proceeds backward, producing the sequence testC, testB, and testA. The successful execution of all tests confirms that the custom ordering logic is applied consistently by the JUnit Platform during test discovery and execution.
Example ProjectDependencies and Technologies Used: - junit-jupiter-engine 6.0.1 (Module "junit-jupiter-engine" of JUnit)
Version Compatibility: 5.4.0 - 6.0.1 Version compatibilities of junit-jupiter-engine with this example:
- 5.4.0
- 5.4.1
- 5.4.2
- 5.5.0
- 5.5.1
- 5.5.2
- 5.6.0
- 5.6.1
- 5.6.2
- 5.6.3
- 5.7.0
- 5.7.1
- 5.7.2
- 5.8.0
- 5.8.1
- 5.8.2
- 5.9.0
- 5.9.1
- 5.9.2
- 5.9.3
- 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
|