JUnit IgnoreRest

Given a scenario that you do not want to run all you test in a test case. For whatever reason you want to run only some of them.

For example: when developing and you find a failing test and when investigation you want to avoid the noise what other test runs are generating (e.g. logging output).

Simple, built in solution is to @Ignore all other but the relevant test case

1  @Test
2  @Ignore
3  public void test1(){...  }
4  @Test
5  @Ignore
6  public void test2(){...  }
7  @Test
8  public void test3(){...  }

Of course it is extremely uncomfortable to do especially when having sever dozens of test methods.

A few days ago I have run into a special annotation called @IgnoreRest in Spock . It simply takes the marked test and executes only that one. All other is ignored.

Of course there is no similar in “standard” JUnit .

How it should look like (identical to the previous sample):

1  @Test
2  public void test1(){...  }
3  @Test
4  public void test2(){...  }
5  @Test
6  @IgnoreRest
7  public void test3(){...  }

Without implementation I had to develop myself. There were many options to implement:

There is one single issue which makes this implementation incomplete: ignored test are not marked as ignored.

At the moment in JUnit version 4.11 there is not way to use RunNotifier (that is the way IDEA is able to display ignored test properly). At the moment the official answer is to use Assume. Once an assume exception is raised JUnit is ignoring the result but not calling RunNotifier as in case of @Ignore. So even if the solution is working properly IDEs are not displaying it properly so it is much difficult to notice if you forget to clean up @IgnoreRest.

NB: All source is available on Github in package eu.qualityontime.test

A specific test case

 1  @Rule
 2  public IgnoreRestRule rule = new IgnoreRestRule();
 3
 4  @Test
 5  public void test1() throws Exception {
 6    assertTrue(false);
 7  }
 8
 9  @Test
10  public void test2() throws Exception {
11    assertTrue(false);
12  }
13
14  @Test
15  public void test3() throws Exception {
16    assertTrue(false);
17  }
18
19  @Test
20  @IgnoreRest
21  public void test4() throws Exception {
22    assertTrue(true);
23  }

The marker IgnoreRest

1  @Retention(RetentionPolicy.RUNTIME)
2  @Target({ ElementType.METHOD })
3  public @interface IgnoreRest {}

IgnoreRestRule

 1  
 2  import java.lang.reflect.Method;
 3  import org.junit.Assume;
 4  import org.junit.rules.TestWatcher;
 5  import org.junit.runner.Description;
 6  import org.junit.runners.model.Statement;
 7
 8  public class IgnoreRestRule extends TestWatcher {
 9
10    @Override
11    public Statement apply(Statement base, Description description) {
12      if (isIgnorable(description)) {
13        return new Statement() {
14          @Override
15          public void evaluate() throws Throwable {
16            Assume.assumeFalse("IgnoreRest", true);
17          }
18        };
19      }
20      return super.apply(base, description);
21    }
22
23    private boolean isIgnorable(Description description) {
24      return hasIgnoreRestAnnotation(description) && null == description.getAnnotation(IgnoreRest.class);
25    }
26
27    private boolean hasIgnoreRestAnnotation(Description description) {
28      Class<?> c = description.getTestClass();
29      for (Method m : c.getDeclaredMethods()) {
30        if (null != m.getAnnotation(IgnoreRest.class)) {
31          return true;
32        }
33      }
34      return false;
35    }
36  }
37
Jul 03, 2014
comments powered by Disqus

Links

Cool

RSS