Run JUnit tests in Method Order With Custom Annotation

By default JUnit does not support to run JUnit tests in method order. JUnit only provides to run ordered method execution by name ascending NAME_ASCENDING or descending JVM.

It is a bad practice to depend on the order of execution of your unit tests. But sometimes you have hit a brick wall and you need the specific order of execution.

Creating JUnit tests in Method Order

We can use the @RunWith annotation to map our custom OrderedRunner class that will sort the method executions via our custom @Order annotation.

package com.memorynotfound.test;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(OrderedRunner.class)
public class OrderedJUnitTest {

    @Test
    @Order(order = 2)
    public void second(){
        System.out.println("second");
    }

    @Test
    @Order(order = 3)
    public void third(){
        System.out.println("third");
    }

    @Test
    @Order(order = 1)
    public void first(){
        System.out.println("first");
    }
}

Creating custom order annotation

The @Order annotation takes an int that will be used to determine the order.

package com.memorynotfound.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface Order {
    public int order();
}

Creating custom orderedRunner

This class does the actual ordering of our JUnit methods.

package com.memorynotfound.test;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class OrderedRunner extends BlockJUnit4ClassRunner {

    public OrderedRunner(Class<?> clazz) throws InitializationError {
        super(clazz);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        List<FrameworkMethod> list = super.computeTestMethods();
        List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
        Collections.sort(copy, new Comparator<FrameworkMethod>() {
            @Override
            public int compare(FrameworkMethod f1, FrameworkMethod f2) {
                Order o1 = f1.getAnnotation(Order.class);
                Order o2 = f2.getAnnotation(Order.class);

                if (o1 == null || o2 == null)
                    return -1;

                return o1.order() - o2.order();
            }
        });
        return copy;
    }
}

Output

As you can see the method execution is in the indicated order.

first
second
third

Be advised that normally you must implement your unit tests to run independently. But now you have a way you can run JUnit tests in Method Order.

References

Download

You may also like...

  • Leonid Samarkin

    Excellent!
    Thank you