StackTips
 7 minutes

Order of Test Methods in JUnit5

By Nilanchala @nilan, On Feb 17, 2024 JUnit 5 2.21K Views

The @Test a JUnit annotation that will execute the method when the tests starts. A test class can contain one or more test methods. When there are multiple test methods, the order of execution is not fixed.

The @TestMethodOrder is a type-level annotation that is used to configure a method orderer for the test methods of the annotated test class or test interface. The @TestMethodOrder can be defined in your test class, inherited from parent class or declared on a test interface implemented by a test class.

The @TestMethodOrder offers different ways to order test execution order. We can order by either DisplayName, MethodName, Random, OrderAnnotation or based on a custom order.

Title Please note, the Alphanumeric annotation is deprecated and internally uses the MethodName order.

Order Test Methods by MethodName

Following code demonstrates how to order test methods based on the MethodName. The same applies for Random as well.

import org.junit.jupiter.api.MethodOrderer;  
import org.junit.jupiter.api.Test;  
import org.junit.jupiter.api.TestMethodOrder;  
  
import static org.junit.jupiter.api.Assertions.assertTrue;  
  
@TestMethodOrder(MethodOrderer.MethodName.class)  
class MyServiceTests {  
  
    @Test  
    void test1() {  
        assertTrue(true);  
    }  
  
    @Test  
    void test2() {  
        assertTrue(true);  
    }  
  
    @Test  
    void test3() {  
        assertTrue(true);  
    }  
}

Prints:


Order Test Methods by DisplayName

The @DisplayName is used when the test report is generated. For ordering the test methods by display name we need to specify a custom display name for each test using the @DisplayName annotation.

import org.junit.jupiter.api.DisplayName;  
import org.junit.jupiter.api.MethodOrderer;  
import org.junit.jupiter.api.Test;  
import org.junit.jupiter.api.TestMethodOrder;  
  
import static org.junit.jupiter.api.Assertions.assertTrue;  
  
@TestMethodOrder(MethodOrderer.DisplayName.class)  
class MyServiceTests {  
  
    @Test  
	@DisplayName("testMethod1")  
	void test1() {   
        assertTrue(true);  
    }  
  
    @Test  
    @DisplayName("testMethod2")  
    void test2() {  
        assertTrue(true);  
    }  
  
    @Test  
    @DisplayName("testMethod3")  
    void test3() {  
        assertTrue(true);  
    }  
}

Prints: 


Order Test Methods by OrderAnnotation

To define the test execution order based on the OrderAnnotation, we need to declare @Order annotation for each test methods.

Please note that the @Order annotation should be from org.junit.jupiter.api package not from the spring framework org.springframework.core.annotation package.

import org.junit.jupiter.api.MethodOrderer;  
import org.junit.jupiter.api.Order;  
import org.junit.jupiter.api.Test;  
import org.junit.jupiter.api.TestMethodOrder;  
import static org.junit.jupiter.api.Assertions.assertTrue;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)  
class MyServiceTests {  
  
    @Test  
    @Order(1)  
    void test1() {  
        assertTrue(true);  
    }  
  
    @Test  
    @Order(3)  
    void test2() {  
        assertTrue(true);  
    }  
  
    @Test  
    @Order(2)  
    void test3() {  
        assertTrue(true);  
    }  
}

Prints:

Defining Custom Order

We can define custom order by extending the existing method orderers. For example, let us create a custom method order by number of parameters passed to the test. The test with more parameters will be executed first.

import java.util.Comparator;

class ParameterCountOrder implements MethodOrderer {  
    @Override  
    public void orderMethods(MethodOrdererContext context) {  
        Comparator<MethodDescriptor> comparator =  
                Comparator.comparingInt(md1 -> md1.getMethod().getParameterCount());  
        context.getMethodDescriptors()  
                .sort(comparator.reversed());  
    }  
}

Now, let us use the custom MethodOrderer we have created above.

import org.junit.jupiter.api.DisplayName;  
import org.junit.jupiter.api.Test;  
import org.junit.jupiter.api.TestMethodOrder;  
import org.junit.jupiter.params.ParameterizedTest;  
import org.junit.jupiter.params.provider.CsvSource;  
import static org.junit.jupiter.api.Assertions.assertTrue;

@TestMethodOrder(ParameterCountOrder.class)  
class MyServiceTests {  
  
    @Test  
    @DisplayName("testMethod1")  
    void test1() {  
        assertTrue(true);  
    }  
  
    @ParameterizedTest(name = "{index} ==> product={0}")  
    @CsvSource({  
            "iPhone 15",  
            "Mx Master 3S"  
    })  
    @DisplayName("testMethod2")  
    void test2(String product) {  
        assertTrue(true);  
    }  
  
    @DisplayName("testMethod3")  
    @ParameterizedTest(name = "{index} ==> product={0}, price={1}")  
    @CsvSource({  
            "iPhone 15, 999",  
            "Mx Master 3S, 89"  
    })  
    void test3(String product, double price) {  
        assertTrue(true);  
    }  
  
}

Prints:


nilan avtar

Nilanchala

I'm a blogger, educator and a full stack developer. Mainly focused on Java, Spring and Micro-service architecture. I love to learn, code, make and break things.