1

I have one TestCase class, whcih has 5 test methods. I can directly execute this class, then all the test methods will be executed. This is fine.

Suppose If I want to execute few test methods(but not all) and those methods will be decided based on certain condition at run time, what is the solution..?

To be more clear,

I have a TestCase class "MyTestCase"

public class MyTestCase extends TestCase
{
    @Test
    public void test1()
    {
        ....
    }    
    @Test
    public void test2()
    {
        ....
    }    
    @Test
    public void test3()
    {
        ....
    }    
    @Test
    public void test4()
    {
        ....
    }      
    @Test
    public void test5()
    {
        ....
    }
}

If I run this class, all the tests will be executed.

But my requirement is: I don't want all methods to be executed always. Sometimes 2 methods or 3 methods or 4 methods etc....

I have an XML file, which decides what test methods have to be executed. Whatever is there in the XML file, only those test methods should be executed. (I have a class, which reads the XML file to get the test method names.)

Is there any way to control no of test methods to be executed in a TestCase class at run time....?

I think I have to use TestSuite class. But I am not sure on how to use it exactly. Can any one help in solving this problem...?

Thanks in advance, Sunil

Ajay George
  • 11,759
  • 1
  • 40
  • 48
Sunil
  • 59
  • 1
  • 5
  • A conditional executed test is a bad smell since it adds complexity. What your reason behind it? A test should be executed each run automatically and if it needs execution I suggest to split each method up into it's own case. – Frank May 23 '13 at 07:59

1 Answers1

0

You can use a custom TestRunner to execute this.

public class SelectiveJunitRunner extends BlockJUnit4ClassRunner {

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

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        //Inject ignore List
        List<String> ignoreList = Arrays.asList("test2","test4");
        List<FrameworkMethod> computeTestMethods = super.computeTestMethods();
        List<FrameworkMethod> filteredList = new ArrayList<>();
        for (FrameworkMethod frameworkMethod : computeTestMethods) {
            if (!ignoreList.contains(frameworkMethod.getName()))
                filteredList.add(frameworkMethod);
        }
        return filteredList;
    }



}

Junit Test case

@RunWith(SelectiveJunitRunner.class)
public class SelectiveTest {

    @Test
    public void test1() {
        System.out.println("1");
    }
    @Test
    public void test2() {
        System.out.println("2");
    }
    @Test
    public void test3() {
        System.out.println("3");
    }
    @Test
    public void test4() {
        System.out.println("4");
    }

}
Ajay George
  • 11,759
  • 1
  • 40
  • 48
  • I tried it..It didn't work. When I ran the JUnit TestCase, Its throwing IllegalArgumentException(in SelectiveJUnitRunner class). – Sunil May 23 '13 at 10:42
  • Yes, I am on JUnit4. When I run your code, it is running fine. But when I apply the same rule on my code, It is throwing an exception. Exception is: java.lang.IllegalArgumentException: Test class should have exactly one public zero argument constructor at com...SelectiveJUnitRunner. My TestCase class has one constructor, which takes connection parameter. If I run this Test class, I am getting the above exception. Later I introduced another constructor(a zero-argument), Still I am getting an exception: Test class can have only one constructor. I tried both ways, still not working... – Sunil May 24 '13 at 05:34
  • You should not have a constructor in your Junit Test case. More on that [here](http://stackoverflow.com/questions/6094081/junit-using-constructor-instead-of-before). Create the connection object in `@BeforeClass` or `@Before`. – Ajay George May 24 '13 at 13:53