Close

JUnit 5 - Custom ClassOrderer Implementation

[Last Updated: Dec 25, 2025]

Similar to MethodOrderer, JUnit 5 allows creating custom ClassOrderer implementations for controlling test class execution order. This is useful for organizing test suites, managing dependencies between test classes, or implementing complex test orchestration logic.

Implementing ClassOrderer

Custom ClassOrderers implement the ClassOrderer interface and override the orderClasses method. This method receives a ClassOrdererContext containing test class descriptors and returns an ordered list of classes.

ClassOrderer interface

 package org.junit.jupiter.api;
 .....
 public interface ClassOrderer {
 void orderClasses(ClassOrdererContext context);
 ...
 }
 

Definition of ClassOrdererContext

Version: 6.0.0
 package org.junit.jupiter.api;
 @API(status = STABLE, since = "5.10")
 public interface ClassOrdererContext {
     List<? extends ClassDescriptor> getClassDescriptors(); 1
     Optional<String> getConfigurationParameter(String key); 2
 }
1Get the list of ClassDescriptor to order.
2Get the configuration parameter stored under the specified key.

Example

Implementing custom ClassOrderer

Following is a custom ClassOrderer that sorts classes by their simple name's length.

package com.logicbig.example;

import org.junit.jupiter.api.ClassDescriptor;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.ClassOrdererContext;
import java.util.Comparator;

public class OrderAnnotationClassOrderer implements ClassOrderer {

    @Override
    public void orderClasses(ClassOrdererContext context) {
        context.getClassDescriptors().sort(
                Comparator.comparingInt(
                        (ClassDescriptor o) ->
                                getSimpleClassLength(o))
        );
    }

    private static int getSimpleClassLength(ClassDescriptor o) {
        return o.getTestClass()
                .getSimpleName().length();
    }
}

Test classes

package com.logicbig.example;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static org.junit.jupiter.api.Assertions.assertTrue;

@TestClassOrder(OrderAnnotationClassOrderer.class)
class CustomClassOrdererTest {

    @Nested
    class ParserTestClass {

        @Test
        void testB() {
            assertTrue(true);
        }
    }

    @Nested
    class CalcClass {

        @Test
        void testA() {
            assertTrue(true);
        }
    }

    @Nested
    class IntegrationTestClass {

        @Test
        void testC() {
            assertTrue(true);
        }
    }
}

Output

$ mvn  test -Dtest=CustomClassOrdererTest
[INFO] Scanning for projects...
[INFO]
[INFO] --< com.logicbig.example:junit-5-custom-class-orderer-implementation >--
[INFO] Building junit-5-custom-class-orderer-implementation 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-custom-class-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-class-orderer-implementation\src\main\resources
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ junit-5-custom-class-orderer-implementation ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-custom-class-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-class-orderer-implementation\src\test\resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ junit-5-custom-class-orderer-implementation ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- surefire:3.5.0:test (default-test) @ junit-5-custom-class-orderer-implementation ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] +--.--com.logicbig.example.CustomClassOrdererTest$CalcClass - 0.158 ss
[INFO] | | '-- [OK] testA - 0.087 ss
[INFO] +--.--com.logicbig.example.CustomClassOrdererTest$ParserTestClass - 0.158 ss
[INFO] | | '-- [OK] testB - 0.027 ss
[INFO] +-----com.logicbig.example.CustomClassOrdererTest$IntegrationTestClass - 0.158 ss
[INFO] | '-- [OK] testC - 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: 4.935 s
[INFO] Finished at: 2025-12-22T17:18:01+08:00
[INFO] ------------------------------------------------------------------------

As shown in the test execution output above, the custom ClassOrderer successfully sorted the nested test classes in ascending order based on the length of their simple names. The classes were executed in this sequence: CalcClass (8 characters), ParserTestClass (15 characters), and IntegrationTestClass (21 characters). This demonstrates how a custom ClassOrderer can control the execution order of nested test classes according to specific sorting criteria, providing flexibility in test organization and execution flow.

Example Project

Dependencies and Technologies Used:

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

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

    • 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

JUnit 5 - Custom ClassOrderer Implementation Select All Download
  • junit-5-custom-class-orderer-implementation
    • src
      • test
        • java
          • com
            • logicbig
              • example
                • OrderAnnotationClassOrderer.java

    See Also