tags:

views:

250

answers:

3

I have the classical structure for tests, I have a test suite of different suites like DatabaseTests, UnitTests etc. Sometimes those suites contains other suites like SlowDatabaseTests, FastDatabaseTests etc.

What I want is to randomize the running order of tests so I will make sure they are not dependent to each other. Randomization should be at every level, like suite should shuffle test class order, and test class should shuffle test method order.

If it is possible to do this in Eclipse that will be the best.

A: 

I will make sure they are not dependent to each other

You should make sure that this is the case without relying on random execution order. What makes you fear that dependencies may exist?

May I ask why people downvote my answer? What is wrong with it?
We are being very careful while writing unit tests and making them independent. But we are also writing production code very careful, bugs happen to appear, there is no guarantee that they will be independent.PS. We are using JUnit for not only unit tests but for functional tests too, so they sometimes leave the DB at some state.
nimcap
@lutz I guess because you countered with another question without answering OP's question
Adrian
+3  A: 

In general what you need to do is to write your own test runner and in the test runner class aggregate the methods and randomly run each test (make sure you don't run a test twice).

Read more about the test framework and how to write your own test runner here: http://www.ddj.com/architect/184415674

Note that the ddj.com article describes the JUnit3 test runner. If you try this, be aware that if your tests use TestSetup or try to do suite-level setup and tear down by extending TestSuite, the approach suggested here won't work; the test runner doesn't "see" TestSuites or TestDecorators. Writing your own JUnit3 test runner also won't work if you run tests from an IDE like Eclipse.
NamshubWriter
+2  A: 

You do have a Sortable but I can't see how you would use it.

You could extend BlockJUnit4ClassRunner and have computeTestMethods() return a randomized copy of super.computeTestMethods(). Then use the @RunWith to set that as the runner to use.

e.g.

package com.stackoverflow.mlk;

import java.util.Collections;

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

public class RandomBlockJUnit4ClassRunner extends BlockJUnit4ClassRunner {

    public RandomBlockJUnit4ClassRunner(Class<?> klass)
      throws InitializationError {
     super(klass);
    }

    protected java.util.List<org.junit.runners.model.FrameworkMethod> computeTestMethods() {
     java.util.List<org.junit.runners.model.FrameworkMethod> methods = super.computeTestMethods();
     Collections.shuffle(methods);
     return methods;
    }

}

Then

@RunWith(com.stackoverflow.mlk.RandomBlockJUnit4ClassRunner.class)
public class RandomOrder {
    @Test
    public void one() {
    }

    @Test
    public void two() {
    }

    @Test
    public void three() {
    }
}
mlk
good answer but not quite sufficient I need to implement a Suite runner too, to randomize test classes order. Besides I have lots of tests and I don't want to put @RunWith annotation into all of them. I think that can be handled in Suite runner
nimcap