Enterprise Java

Test Execution Order in JUnit 5

The general practices say that automated tests should be able to run independently and with no specific order as well as the result of the test should not depend on the results of previous tests. But there are situations where a specific order of test execution can be justified, especially in integration or end to end tests.

By default, in JUnit 5 the execution of test methods is repeatable between builds hence deterministic but the algorithm is intentionally non-obvious (as authors of the library state). Fortunately, execution order can be adjusted to our needs using either built-in method orderers or by creating custom ones.

org.junit.jupiter.api.TestMethodOrder

In order to change test execution order we need to annotate the test class with org.junit.jupiter.api.TestMethodOrder and pass the type of method orderer as an argument. As of JUnit 5.4 there are three built-in method orderers: OrderAnnotation, Alphanumeric and Random. We can also easily create our own custom method orderer by implementing org.junit.jupiter.api.MethodOrderer interface.

Ordering with @Order annotation

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package pl.codeleak.samples.junit5.basics;
 
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
 
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class TestExecutionOrderWithOrderAnnotation {
 
    @Order(1)
    @Test
    void aTest() {}
 
    @Order(2)
    @Test
    void bTest() {}
 
    @Order(3)
    @Test
    void cTest() {}
 
}

Alphanumeric ordering

01
02
03
04
05
06
07
08
09
10
11
12
13
@TestMethodOrder(MethodOrderer.Alphanumeric.class)
class AlphanumericTestExecutionOrder {
 
    @Test
    void aTest() {}
 
    @Test
    void bTest() {}
 
    @Test
    void cTest() {}
 
}

Random ordering

Random ordering can be useful if want to make sure that order of method execution is not deterministic between builds.

01
02
03
04
05
06
07
08
09
10
11
12
13
@TestMethodOrder(MethodOrderer.Random.class)
class AlphanumericTestExecutionOrder {
 
    @Test
    void aTest() {}
 
    @Test
    void bTest() {}
 
    @Test
    void cTest() {}
 
}

Random method orderer is using System.nanoTime() as the seed but it can be changed using junit.jupiter.execution.order.random.seed configuration property. The value of this property should return any String that can be converted using Long.valueOf(String).

One way of configuring the seed is to provide the configuration property in junit-platform.properties configuration file:

1
junit.jupiter.execution.order.random.seed=42

Custom ordering

Creating a custom method orderer can be done by implementing org.junit.jupiter.api.MethodOrderer interface and providing it as the argument to @TestMethodOrder.

The below example is a method orderer that sorts methods by their names length:

01
02
03
04
05
06
07
08
09
10
class MethodLengthOrderer implements MethodOrderer {
 
    private Comparator<MethodDescriptor> comparator =
            Comparator.comparingInt(methodDescriptor -> methodDescriptor.getMethod().getName().length());
 
    @Override
    public void orderMethods(MethodOrdererContext context) {
        context.getMethodDescriptors().sort(comparator);
    }
}

And the use:

01
02
03
04
05
06
07
08
09
10
11
12
13
@TestMethodOrder(MethodLengthOrderer.class)
class CustomTestExecutionOrder {
 
    @Test
    void aTest() {}
 
    @Test
    void abTest() {}
 
    @Test
    void abcTest() {}
 
}

Summary

Having a way of adjusting test execution order in JUnit 5 can be useful in certain situation and I am glad to see this feature. I believe in most cases built-in method orderers will be more than enough. If not, there is an easy way of implementing a custom one.

Find examples from used in this article (along with many more) on GitHub: https://github.com/kolorobot/junit5-samples/tree/master/junit5-basics

Published on Java Code Geeks with permission by Rafal Borowiec, partner at our JCG program. See the original article here: Test Execution Order in JUnit 5

Opinions expressed by Java Code Geeks contributors are their own.

Rafal Borowiec

Software developer, Team Leader, Agile practitioner, occasional blogger, lecturer. Open Source enthusiast, quality oriented and open-minded.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button