简体   繁体   中英

Extending Junit ParentRunner Class to filter test methods

I have a requirement of reading a text file which contains list of all the testmethods in yes/no value and to pick the "yes" marked testmethods only for a TestCase Class,and to execute in Junit.

So I have written a script to read the file and to group it in a map< TestCaseName,ArrayList_ofEnabledTestMethods > . To run that I found one option is to use Assume.assumeTrue() .

But I wanted to try some otherway... instead of writting extra lines before each test methods , So I tried to write a custom runner ( ABCSuite which extends ParentRunner ) and planned to use it in my TestSuite file like below :

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(ABCSuite.class)
@Suite.SuiteClasses({TestCalc.class})
public class BatTest{

}

Here TestCalc.class contains all the test methods some of which is marked "yes" in the earlier mentioned text file .

Please let me know how I can use of extending the ParentRunner class/Junit Libraries to achieve this . If any good tutorial is there or any link which addressed this before please.. share

You can do this by extending BlockJUnit4ClassRunner :

public class FilterRunner extends BlockJUnit4ClassRunner {
  private List<String> testsToRun = Arrays.asList(new String[] { "test1" });

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

  @Override
  protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
    Description description= describeChild(method);
    if (method.getAnnotation(Ignore.class) != null || !testsToRun.contains(method.getName())) {
      notifier.fireTestIgnored(description);
    } else {
      runLeaf(methodBlock(method), description, notifier);
    }
  }
}

You can fill in testsToRun as you like. The above will mark the other tests as Ignored. You use this like:

@RunWith(Suite.class)
@SuiteClasses({Class1Test.class})
public class TestSuite {
}

@RunWith(FilterRunner.class)
public class Class1Test {
  @Test
  public void test1() {
    System.out.println("test1");
  }

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

This produces the following output:

test1

If you don't want to add the @FilterRunner to each test class, look at my answer to How to define JUnit method rule in a suite? .

The JUnit way of implementing this would be an implementation of a Filter . It must be instantiated by the Runner that implements Filterable . Filters are applied recursively through the tree of tests. So you only need to apply that filter once in your base suite.

You need to extend a runner and in the constructor apply the filter. To make things more flexible, you could configure the filters that should be applied with annotations.

I had the same requirement and that worked out well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM