Search code examples
javaunit-testingjunit4junit3

Specifying an order to junit 4 tests at the Method level (not class level)


I know this is bad practice, but it needs to be done, or I'll need to switch to testng. Is there a way, similar to JUnit 3's testSuite, to specify the order of the tests to be run in a class?


Solution

  • If you're sure you really want to do this: There may be a better way, but this is all I could come up with...

    JUnit4 has an annotation: @RunWith which lets you override the default Runner for your tests.

    In your case you would want to create a special subclass of BlockJunit4ClassRunner, and override computeTestMethods() to return tests in the order you want them executed. For example, let's say I want to execute my tests in reverse alphabetical order:

    public class OrderedRunner extends BlockJUnit4ClassRunner {
    
        public OrderedRunner(Class klass) throws InitializationError {
            super(klass);
        }
    
        @Override
        protected List computeTestMethods() {
            List list = super.computeTestMethods();
            List copy = new ArrayList(list);
            Collections.sort(copy, new Comparator() {
                public int compare(FrameworkMethod o1, FrameworkMethod o2) {
                    return o2.getName().compareTo(o1.getName());
                }
            });
            return copy;
        }
    }
    @RunWith(OrderedRunner.class)
    public class OrderOfTest {
        @Test public void testA() { System.out.println("A"); }
        @Test public void testC() { System.out.println("C"); }
        @Test public void testB() { System.out.println("B"); }
    }

    Running this test produces:

    C
    B
    A

    For your specific case, you would want a comparator that would sort the tests by name in the order you want them executed. (I would suggest defining the comparator using something like Google Guava's class Ordering.explicit("methodName1","methodName2").onResultOf(...); where onResultOf is provided a function that converts FrameworkMethod to its name... though obviously you are free to implement that any way you want.