4

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

Stephan202
  • 59,965
  • 13
  • 127
  • 133
Som
  • 4,618
  • 4
  • 29
  • 32
  • Is your list of test methods the method names (test1) or a list of class name + method names (com.mycompany.foo.MyClass#test1)? – Matthew Farwell Aug 10 '12 at 07:32
  • In the map – Som Aug 10 '12 at 07:59
  • @Matthew Please ignore my earlier comment... below is the reply of your post ...In the map< **TestCaseName,ArrayList_ofEnabledTestMethods** > the **ArrayList_ofEnabledTestMethods** consists of only test method names like **test1** .. (not the class name + method names ) – Som Aug 10 '12 at 08:07

2 Answers2

4

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?.

Community
  • 1
  • 1
Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171
  • Matthew..Thanks for the input.. but I want to run the FilterRunner not for each test class but for a suite level , so your above [link] JUnit method rule in a suite? I tried and found it expects a Test method in the suite itself and it runs only that with the given example (that extends BlockJUnit4ClassRunner) , I modified the testsuite little adding a @Test method in it otherwise it was giving the intialization error – Som Aug 11 '12 at 15:05
  • could please let me know how your solution ... of @FilterRunner would be applicable to a entire suite where it includes .... more that one test class which they have many test methods ... and those to be run selectively ( example **map< TestCaseName,ArrayList_ofEnabledTestMethods > **)... – Som Aug 11 '12 at 15:10
2

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.

SpaceTrucker
  • 13,377
  • 6
  • 60
  • 99