4

What is the best way to enable/disable a junit test based on a Config parameter? Say I have a Config class which dictates some state of the software that makes a given set of tests invalid.

I could put the body of the test in an if statement within the test method, e.g.:

@Test
public void someTest() {
   if(Config.shouldIRunTheTests()) {
      //do the actual test
   }
}

This seems bad because I actually get test passes for these cases when I actually want these tests skipped. Would like something like:

@Test[Config.shouldIRunTheTests()] 
public void someTest() {
    //do the actual test
}

Is this possible?

Ryan R.
  • 2,478
  • 5
  • 27
  • 48

3 Answers3

3

Actually, looks like I found this with google: http://old.nabble.com/How-to-enable-disable-JUnit-tests-programatically---td23732375.html

EDIT:

This worked for me:

@Test 
public void someTest() {
   org.junit.Assume.assumeTrue(Config.shouldIRunTheTests());
   //do the actual test
}
Ryan R.
  • 2,478
  • 5
  • 27
  • 48
3

Actually I think the best solution on this case is to write your own org.junit.Runner. It is not so complicated as it seems. A simple sample would be:

The Runner:

package foo.bar.test;

import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.JUnit4;
import org.junit.runners.model.InitializationError;

public class MyRunner extends Runner {

    private final Runner runner;

    public MyRunner(final Class<?> klass) throws InitializationError {
        super();
        this.runner = new JUnit4(klass);
    }

    @Override
    public Description getDescription() {
        return runner.getDescription();
    }

    @Override
    public void run(final RunNotifier notifier) {
        for (Description description : runner.getDescription().getChildren()) {
            notifier.fireTestStarted(description);
            try {
                // here it is possible to get annotation:
                // description.getAnnotation(annotationType)
                if (MyConfiguration.shallExecute(description.getClassName(), description.getMethodName())) {
                    runner.run(notifier);
                }
            } catch (Exception e) {
                notifier.fireTestFailure(new Failure(description, e));
            }
        }
    }

}

The test case:

package foo.bar.test;

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

@RunWith(MyRunner.class)
public class TestCase {

    @Test
    public void myTest() {
        System.out.println("executed");
    }

}

And configuration class:

package foo.bar.test;

public class MyConfiguration {

    public static boolean shallExecute(final String className, final String methodName) {
        // your configuration logic
        System.out.println(className + "." + methodName);
        return false;
    }

}

Here the cool thing is that you could implement your own annotation, for example: @TestKey("testWithDataBase"), see comments on the example source above. And your configuration object could define if the test should run or not, so you can group tests, what is quite useful when you have a lot of tests that needs to be grouped.

Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
0

Looking at similar problem, I've found another solution proposed in: Conditionally ignoring tests in JUnit 4

which presents the use of org.junit.Assume and (another solution from Junit-ext) the @RunIf annotation.

I hope the link may shorten the search of anyone who looks here :)

Rafał S
  • 813
  • 7
  • 13