Using JUnit Nested Suites with Selenium RC to simulate TestNG suite and grouping annotations

When I use TestNG for my Selenium tests, I really like the BeforeSuite and AfterSuite annotations because then I can share a Selenium session amongst the tests. With nested JUnit suites I can achieve a similar effect, and I can also go some way to grouping my tests to make it easier to create browser specific suites.

The traditional example for a JUnit 4 suite looks like this:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
        MyTest1.class,
        MyTest2.class,
	MyTest3.class
})
public class JunitSuite1 {
}

Where MyTest1, MyTest2 and MyTest3 now form JUnitSuite1.

You do occasionally see examples which use JUnit 4’s @BeforeClass and @AfterClass annotations:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.AfterClass;
import org.junit.BeforeClass;

@RunWith(Suite.class)
@Suite.SuiteClasses({
        MyTest1.class,
        MyTest2.class,
        MyTest3.class
})
public class JunitSuite1 {

    	@BeforeClass 
	public static void runBeforeSuite() {
       		// do something here
    	}

    	@AfterClass 
	public static void runAfterSuite() {
       		// do something here
    	}
}

This means that you can go some way to simulating TestNG’s @BeforeSuite and @AfterSuite methods, because the runBeforeSuite method will run before any of the tests in MyTest1, 2 or 3 and the runAfterSuite will run after all other suite class methods have completed.

I used this in my Selenium Simplified book in conjunction with a Singleton Selenium Manager to share a selenium session across a bunch of tests. So I start up the selenium session with the first test and close it at the Suite level in an @AfterClass annotated method.

JUnit’s @BeforeClass and @AfterClass will nest, so you can create class level setup and tear down even when nested within a suite.

Also since a ‘suite’ instantiates as a class, it means you can nest suites using the same notation e.g.

@RunWith(Suite.class)
@Suite.SuiteClasses({
        JUnitSuite1.class,
        JUnitSuite2.class,
        JUnitSuite3.class
})
public class JunitMegaSuite1 {

    	@BeforeClass 
	public static void runBeforeSuite() {
       		// do something here
    	}

    	@AfterClass 
	public static void runAfterSuite() {
       		// do something here
    	}
}

You can use this type of construct to simulate a ‘grouping’ functionality in JUnit.

i.e. if I want to create a ‘group’ of tests which only work on IE then I can create a Suite which imports only tests for IE in the .SuiteClasses. Then I can do the same for other browsers.

And then I can combine those suites into browser specific suites (which I appended Group to the name) (the class names here pretty much illustrate what I mean) e.g.

@RunWith(Suite.class)
@Suite.SuiteClasses({
        IEOnlyTestsGroup.class,
        AnyBrowserTestGroup.class,
        IEAndOperaOnlyGroup.class
})
public class IESpecificSuite {

    	@BeforeClass 
	public static void runBeforeSuite() {
       		// do something here
    	}

    	@AfterClass 
	public static void runAfterSuite() {
       		// do something here
    	}
}

If you combine this suite type definition with conditional tasks in Ant then you can go quite a long way to creating browser specific test runs fairly easily with out of the box functionality of JUnit 4.x and Ant. Not quite as powerful a grouping method as TestNG’s but at least this makes grouping possible and simple within JUnit 4.

You can find a pretty good set of usage examples of JUnit 4 suites in this post on Lasse’s weblog particularly when you read down through the comments.

If you have any alternative ways of aiding your functional testing with suites and groups in JUnit, then please leave a comment.

This entry was posted in Selenium Simplified Blog, Selenium-RC and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *