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
Java source and doc
Definition of TestMethodOrderVersion: 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
}
It can only be used on class level.
Definition of TestClassOrderVersion: 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
}
It can only be used on class level.
Definition of OrderVersion: 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
}
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 MethodOrdererVersion: 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
...
}
}
Definition of ClassOrdererVersion: 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
...
}
}
In next tutorials we will see the examples related to JUnit test execution order.
|