Giving JUnit something like TestNG.@BeforeSuite

JUnit is the Undisputed King of Java unit test Libraries.

TestNG has a way more compreensive lifecycle management using @Before/@After annotations. If you wanna know more, there is a good presentation about testNG on prezi. Slide 22 shows how @Before/After works.

For me, @BeforeSuite is pretty much essential writting integrations test.

@BeforeSuite: "the annotated method will be run before all tests in this suite have run."

And you can’t do that with JUnit!

People that do not understand what @BeforeSuite does suggests using @BeforeClass. Well, guess what, it ain’t the same.

The closest JUnit can get to @BeforeSuite is having a TestSuite annotated with @BeforeClass, but that means you need to manually keep track of your tests:

@RunWith(MySuite.class)
@SuiteClasses({FooTest.class, BarTest.class, BazTest.class});

Serious? 2016! For each new test, you need to "remember" to update this. NO WAY! This is so freaking insane!

A better way

So, what alternative can I offer? @ClassRule + singleton.

Yeah, I openned the laptop to suggest people: use a singleton.

shame.jpg

Well, pick your poison, manual, error prone Suite or shameful singleton.

Example

On each test, I included my @RuleClass, pointing to a singleton:

public class Test[12] {

    @ClassRule
    public static SuiteRule rule = SuiteRule.INSTANCE;

    @Test
    public void setup() {
        System.out.println("Test[12]");
    }

}

And the rule would be something like this:

    public static final SuiteRule INSTANCE = new SuiteRule();

    private final AtomicBoolean initialized = new AtomicBoolean();

    @Override
    public Statement apply(Statement base, Description description) {
        if (!initialized.get()) {
            beforeSuite(description);
            initialized.set(true);
        }

        return base;
    }

    protected void beforeSuite(Description description) {
        System.out.println("Before suite");
    }

Running this example printed this:

Before suite
Test1
Test2

No rocket science, quite the oposite, a very trivial piece of code, using design patterns that I don’t even like, but since I saw so many people asking for it and no good answer, I decided to document a better alternative.

The entire example is on github.

comments powered by Disqus