How can I automatically skip certain JUnit tests based on a condition?
Asked Answered
L

1

8

I would like a simple way to assign a priority value to my JUnit tests such that I can say 'run only priority 1 tests', 'run priority 1, 2 and 3 tests' etc. I am aware that I could just include a line like Assume.assumeTrue("Test skipped for priority " + priority, priority <= 2); at the start of each test (where priority is the highest value priority tests I want to run and 2 is the priority value of this particular test), however copy-pasting a line at the start of each test doesn't seem a very good solution.

I have tried writing a solution using a simple annotation which is detected by the JUnit Rule I am using anyway:

public class Tests {
    @Rule
    public TestRules rules = new TestRules();
    @Test
    @Priority(2)
    public void test1() {
        // perform test
    }
}

public class TestRules extends TestWatcher {
    private int priority = 1; // this value is manually changed to set the priority of tests to run
    @Override
    protected void starting(Description desc) {
        Priority testCasePriority = desc.getAnnotation(Priority.class);
        Assume.assumeTrue("Test skipped for priotity " + priority, testCasePriority == null || testCasePriority.value() <= priority);
    }
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Priority {
    public int value() default 0;
}

While this appears to work (the correct tests are shown as skipped in the Eclipse JUnit view) the tests are still performed, i.e. any code in test1() is still run.

Does anyone have any idea how I can get the Assume in my Rule to actually skip the test?

Loriloria answered 16/2, 2016 at 11:1 Comment(2)
This might help :- #1689742Disrespect
... or this might help: codeaffine.com/2013/11/18/…Kistna
M
5

The exception thrown by a TestWatcher.starting are ignored, and rethrown at the end of the test.

You should implement a TestRule instead of a TestWatcher :

public class TestRules implements TestRule {
    private int priority = 1; // this value is manually changed to set the priority of tests to run

     public Statement apply(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                Priority testCasePriority = desc.getAnnotation(Priority.class);
                Assume.assumeTrue("Test skipped for priotity " + priority, testCasePriority == null || testCasePriority.value() <= priority);

                base.evaluate();
            }
        };
    }
}
Monody answered 16/2, 2016 at 11:7 Comment(2)
I have other starting(), failed() and finished() methods in my TestWatcher subclass, are these simple to recreate in a TestRule or is it worth creating a separate TestRule for my Assume method in addition to my existing TestWatcher subclass?Loriloria
look at the source of TestWatcher : it's just a simple delegating implementation of a TestRule. You can easily reimplements your TestWatcher from a TestRule : github.com/junit-team/junit/blob/master/src/main/java/org/junit/…Prehistoric

© 2022 - 2024 — McMap. All rights reserved.