OSGi Testsuite: Introducing Classname Filters

Home  >>  Eclipse  >>  OSGi Testsuite: Introducing Classname Filters

OSGi Testsuite: Introducing Classname Filters

On November 12, 2014, Posted by , In Eclipse,JUnit,OSGi, By ,, , With 4 Comments

OSGi Testsuite is a JUnit test-runner that collects dynamically test classes for execution. It has been published by my fellow Rüdiger about a year ago and proven useful in some projects already. However for gonsole we had to use an ugly patch because version 1.0 only supported .*Test postfix matching for test class names.

I solved this problem with version 1.1 by introducing an annotation @ClassnameFilters that
uses regular expressions to match arbitrary name patterns. This post explains in short how it works.

 Testing with JUnit

Testing with JUnit Book

Testing with JUnit is one of the most valuable skills a Java developer can learn. No matter what your specific background, whether you’re simply interested in building up a safety net to reduce regressions of your desktop application or in improving your server-side reliability based on robust and reusable components, unit testing is the way to go.

Frank has written a book that gives a profound entry point in the essentials of testing with JUnit and prepares you for test-related daily work challenges.

  Get It Now! 

OSGi Testsuite

OSGi Testsuite provides a JUnit test runner BundleTestSuite that can be used to run all tests within a given number of OSGi bundles. To use it annotate a class with @RunWith(BundleTestSuite.class) and specify the bundles with @TestBundles({"bundle.1", ...}). When run JUnit will process all classes in the listed bundles, which have a name ending with 'Test'.

@RunWith( BundleTestSuite.class )
@TestBundles( { "org.example.bundle1", "org.example.bundle2" } )
public class MasterTestSuite {}

Unfortunately the Test postfix fixation has turned out to be a bit too inflexible. Within gonsole we use different postfixes for unit and integration tests. And we do not want the unit tests to be executed within the OSGi Testsuite run. But this distinction is not possible with version 1.0.

See also  SWT Look and Feel: Customize FlatScrollBar Color and More

ClassnameFilters

Inspired by ClasspathSuite (which works similar to OSGi Testsuite on plain JUnit tests) I introduced an annotation @ClassnameFilters. This allows to define filters based on regular expressions to match arbitrary test name patterns:

@RunWith( BundleTestSuite.class )
@TestBundles( { "org.example.bundle1", "org.example.bundle2" } )
@ClassnameFilters( { ".*ITest" } )
public class IntegrationTestSuite {}

Processing the example would include all the tests of classes in the listed bundles, which have a name ending with the 'ITest' postfix. Note that classes with the simple 'Test' postfix would not be processed.

Furthermore it is possible to specify exclusion patterns using a leading '!':

@RunWith( BundleTestSuite.class )
@TestBundles( { "org.example.bundle1", "org.example.bundle2" } )
@ClassnameFilters( { ".*ITest", "!.*FooITest" } )
public class IntegrationTestSuite {}

The given example would now execute all the tests of classes in the listed bundles, which have a name ending with 'ITest' postfix except for classes whose names end with ‘FooITest’. Simple enough, isn’t it?

Conclusion

OSGi Testsuite has been enhanced with a filter mechanism for dynamic execution of test classes that matches arbitrary name patterns. Filter specification is done easily using the ClassnameFilters annotation and regular expressions.

The code is available under the Eclipse Public License and hosted on GitHub:

https://github.com/rherrmann/osgi-testsuite

The latest stable version can be obtained from this p2 repository:

https://rherrmann.github.io/osgi-testsuite/repository

For feedback whatsoever, please leave a comment or file an issue.

Frank Appel
Follow me

4 Comments so far:

  1. Sébastien Gandon says:

    Hello,
    Interesting post. We have done something very similar but we have completely externalized the bundles and classes definition using a properties file so that we never have to touch to the TestSuite which is completely generic.
    This have help us decouple the writing of test from the launching, we have dev teams developing Unit test, other team developing SWTBot test and other people setp the launch of those test.
    Thanks to a naming convention for all those tests (bundle and class naming convention). We do not have to touch the TestSuite nor the configuration files.

    here is an example for our unit tests :
    #plugin where is located the test suite
    unit.test-plugin-name = test.all.test.suite
    #class name of the test suite
    unit.test-class-name = org.talend.test.GenericTestsJUnit4Suite
    #the following properties defines the way to find all the classes that we want to test
    #This may be a list of comma separated prefixes or be empty
    unit.test.plugin.prefix=org.talend
    #This may be a list of comma separated suffixes or be empty
    unit.test.plugin.suffix=.test
    #This may be a list of comma separated prefixes or be empty
    unit.test.package.prefix=org.talend,com.amalto
    #filter of the class name, you may use the * wildcard
    unit.test.class.filter=*Test
    #specify if the collection of test classes must be done solely within fragments or not
    unit.test.only.fragments=true

    • Frank Appel says:

      Hi Sébastien,

      sounds indeed similar and looks as if you have some interesting additional capabilities like filtering plugins with prefix and postfix patterns. That’s something I was thinking about for the next development step, too.. ;-)

      Frank

  2. Sébastien Gandon says:

    There is also a way to find the proper bundles that have tests embedded instead of either having to maintain a list a bundles in the TestSuite, just like you do with your @TestBundles bundle annotation.
    This allow to avoid such maintenance and decouple teams too.
    Of course all bundles could be looked into for finding the proper classes but this would be too long this is why we have also some filtering pattern for the bundle names as well.

    • Frank Appel says:

      Yes – I was thinking about using inclusion and exclusion patterns for the @TestBundles annotations too. This would ease maintenance indeed as one do not have to add every new bundle to the list. Maybe you would like to contribute some ideas… ;-)