Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create nested TestSuites in JUnit 4.x?

I'm trying to add JUnit to a large project and am having difficulties nesting test suites. For example:

@RunWith(Suite.class)
@Suite.SuiteClasses({Test2.class, .....})
public class Test1{
}

@RunWith(Suite.class)
@Suite.SuiteClasses({Test3.class, .....})
public class Test2{
  //might have tests
}

@RunWith(Suite.class)
public class Test3{
  //tests here
}

Each class runs the tests in it's own package, as well as all sub-package TestSuites

Running Test1 results in java.lang.Exception: No runnable methods. How do I get this to work? Is there a better way to organize tests without a without a huge list somewhere?

like image 294
Spyder Avatar asked Jan 30 '12 20:01

Spyder


People also ask

How to run a test suite In JUnit?

In Junit, test suite allows us to aggregate all test cases from multiple classes in one place and run it together. To run the suite test, you need to annotate a class using below-mentioned annotations: With above annotations, all the test classes in the suite will start executing one by one. Steps to create Test Suite and Test Runner.

Is it possible to create nested tests in unit tests?

It’s optional to create nested tests. Still, it helps to create hierarchical contexts to structure the related unit tests together; in short, it helps to keep the tests clean and readable. Let’s see the following example – Tests for a CustomerService. 1.

What is a JUnit 5 nested class?

Nested Class is Placed inside Another Class and is Arranged in a Hierarchical Structure. Learn about Rules, Template & Examples of JUnit 5 Nested Class: We learned about repeating tests with the same data using the annotation @RepeatedTest in our previous tutorial. We explored the various ways for implementation of @RepeatedTest in a class.

What are @RunWith and @suite annotations in JUnit?

In JUnit, both @RunWith and @Suite annotations are used to run the suite tests. This chapter takes an example having two test classes, TestJunit1 & TestJunit2, that run together using Test Suite. Create a java class to be tested, say, MessageUtil.java in C:\>JUNIT_WORKSPACE.


1 Answers

The first problem is that Test3 uses @RunWith(Suite.class), but doesn't contain @Suite.SuiteClasses({Test3.class, .....}). This produces an IntializationError: class 'Test3' must have a SuiteClasses annotation. Since you aren't intending there to be any classes underneath Test3, this annotation should be removed.

The second problem of Exception: No runnable methods is almost always due to forgetting to add @Test to a test. You didn't put the tests in your sample, so I don't know if that's actually the case or not, but it's the most likely cause.

The following is a working version of your code that allows tests to be run from any class:

Test1.java

import org.junit.runner.*;
import org.junit.runners.*;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({Test2.class})
public class Test1 {

}

Test2.java

import org.junit.runner.*;
import org.junit.runners.*;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({Test3.class})
public class Test2 {

}

Test3.java

import static org.junit.Assert.*;

import org.junit.*;

public class Test3 {

    @Test
    public void testTrue(){
        assertTrue(true);
    }
}

As for whether or not there is a better way than to organize things, I guess it just depends on how you decide to create the classes. Since you can add suites to suites, as this demonstrates, you can create smaller chunks of suites that depend on everything, like a tree. For instance, what I generally do is:

AllTestSuite
    TextParsingSuite
    GuiSuite
        SwingSuite
        JavaFXSuite
    FileIOSuite

A test is added to the most relevant suite. In the end, I don't think I have any suite with more than 10 test classes/suites or so. If I do, it's time to make a new sub-suite. In other words, there is no "huge list somewhere", just a lot of smaller lists that are combined together into another list in order to effectively make one big list.

I suppose you could use some tool to dynamically find all of the Java classes containing tests, but JUnit itself doesn't support this behavior (it only runs the tests you tell it to, which I personally think is a good thing).

like image 185
Thunderforge Avatar answered Sep 20 '22 21:09

Thunderforge