Home   Profil   Angebot   Artikel  
Partner   Kontakt   Links   Privates

ClasspathSuite

Eclipse (3.4 and below) does not have support for JUnit testing in a multi project setting. This little tool tackles the problem for JUnit4 test classes and suites. Due to changes in JUnit there are two different versions out.

Download for JUnit 4.5 and above:

Download for JUnit 4.4 and below:

Documentation:

How to Use It

The mechanism is simple. Just create a new project in Eclipse and add all projects that contain tests you want to run to its build path. Now create a class like that:
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;
@RunWith(ClasspathSuite.class)
public class MySuite {}
This will execute all JUnit4 testclasses (those containing methods with the @Test annotation) in the projects classpath.

JAR Files

By default jar files are being ignored but you can include them in the search for tests by adding another annotation:
import org.junit.extensions.cpsuite.ClasspathSuite.*;
...
@IncludeJars(true)
public class MySuite...

Filtering

And you don't have to run all tests. Instead you can use another annotation to restrict the tests to run by regex expressions which will be applied onto the class name before adding a test class to the suite:
import org.junit.extensions.cpsuite.ClasspathSuite.*;
...
@ClassnameFilters({"mytests.*", ".*Test"})
public class MySuite...
The filter patterns work disjunctively; if any one filter matches, the class will be added to the suite of tests.

Negation Filters

Excluding tests from the test suite can be done by regular expressions but that is very cumbersome to write and read. Therefore I added the feature to have filters that specify a regular expression to exclude certain tests:
@ClassnameFilters({"mytests.*", "!.*AllTests"})
Negation expressions are preceded by a "!". In the previous example all tests that match "mytests.*" will be run except those matching ".*AllTests".

You can have as many positive and negative filters as you like. The positve filters still work disjunctively whereas the negated filters will subtract all matching tests after the maximum set of tests to run has been determined. Having only negated filters starts with the full set of tests.

Abstract Test Classes

ClasspathSuite solves another problem (bug?) in the JUnit 4 integration of Eclipse 3.2: test classes derived from an abstract test class which do not have test methods of their own are being ignored by Eclipse's test runner. When using RunWith(ClasspathSuite.class) you will catch those test classes as well.

Running other RunWith-Suites

So far you would only run "normal" test classes. What about including other test suites that use JUnit's RunWith-Feature? Since version 0.9.5 ClasspathSuites has another annotation in its bag that helps you around that problem: @SuiteTypes(...). Look at the following example:
import org.junit.extensions.cpsuite.ClasspathSuite.*;
import static org.junit.extensions.cpsuite.SuiteType.*;
...
@RunWith(ClasspathSuite.class)
@SuiteTypes(RUN_WITH_CLASSES)
public class AllRunWithSuites {}
This class will execute all test suites in the class path, i.e. classes using the @RunWith annotation. Normal test classes will not be run - unless they are in one of the test suites. If you want both test suites and test class being run use the following expression instead :
@SuiteTypes({RUN_WITH_CLASSES, TEST_CLASSES})
Filtering works the same way it does without the @SuiteTypes annotation (see above).

Running JUnit 3.8 style tests

Since version 1.1.0 ClasspathSuite can also be used to run tests in JUnit 3.8 style, using test classes that are derived from junit.org.TestCase. This feature is disabled by default and you have to tell ClasspathSuite that you want to consider JUnit 3.8 test cases as well:
import org.junit.extensions.cpsuite.ClasspathSuite.*;
import static org.junit.extensions.cpsuite.SuiteType.*;
...
@RunWith(ClasspathSuite.class)
@SuiteTypes(JUNIT38_TEST_CLASSES)
public class AllJUnit38Tests {}
If you want to you can combine JUnit4 and JUnit38 style by specifying more than one suite type, e.g. by using "@SuiteTypes({ JUNIT38_TEST_CLASSES, TEST_CLASSES })". Of course, filtering works here as well.

Base Type Filter

If you want to restrict the execution of test classes to subclasses of a certain base class, you can do it this way:
@BaseTypeFilter(MyBaseTestClass.class)
Use more than one base class if you like:
@BaseTypeFilter({ MyBaseTest.class, YourBaseTest.class })
This works for both JUnit 4 and JUnit 3.8 test classes. The filter is not applied on RunWith suites, though.

Exclude Base Type Filter

Similar to BaseTypeFilter you can specify one or more base classes whose children will be excluded from a test run:
@ExcludeBaseTypeFilter(MyBaseTestClass.class)
Exclude more than one base class if you like:
@ExcludeBaseTypeFilter({ MyExBase.class, YourExbase.class })
ExcludeBaseTypeFilter takes precedence over BaseTypeFilter. The filter works for both JUnit 4 and JUnit 3.8 test classes, but it is not applied on RunWith suites.

Classpath Property Annotation

If you want to use ClasspathSuite via Ant, you sometimes have the need to search tests in a different classpath than the standard one:
@ClasspathProperty("my.class.path")

By default, the classpath that can be retrieved via System.getProperty("java.class.path") will be searched. Using this annotation allows you to point ClasspathSuite at the directories and jar files of your choice.

In case the given property is not set, java.class.path is used as fallback value. This allows you to use the same annotated suite in both Ant and non-Ant context.

BeforeSuite

You can annotate one or more methods with @BeforeSuite to indicate that they should be run once before the full suite will be run.
@BeforeSuite
public static void init() {...}
The signature must be public static void methodName(). An exception during the execution of an annotated method will stop the execution of the suite. The order in which those methods are run is not specified.

Open Issues

Release Notes

Version 1.2.6 2013-01-15

Version 1.2.5 2009-06-25

Version 1.2.4 2009-06-03

Version 1.2.3 2009-05-29

Version 1.2.2 2009-03-07

Version 1.2.1 2009-03-04

Version 1.2.0 beta 2009-03-02

Version 1.1.0 2008-01-18

Version 1.0.0 2007-05-17

Version 0.9.6 2007-02-01

Version 0.9.5 2006-12-21

Version 0.9.1 2006-11-15