JUnit confusion: use 'extends TestCase' or '@Test'?

The distinction is rather easy:

  • extending TestCase is the way unit tests were written in JUnit 3 (of course it's still supported in JUnit 4)
  • using the @Test annotation is the way introduced by JUnit 4

Generally you should choose the annotation path, unless compatibility with JUnit 3 (and/or a Java version earlier than Java 5) is needed. The new way has several advantages:

  • The @Test annotation is more explicit and is easier to support in tools (for example it's easy to search for all tests this way)
  • Multiple methods can be annotated with @Before/@BeforeClass and @After/@AfterClass providing more flexibility
  • Support for @Rule annotations on things like ExpectedException
  • Support for the @Ignored annotation
  • Support for alternative test runners using @RunWith

To test for expected exceptions in a JUnit 3 TestCase you'd have to make the text explicit.

public void testMyException() {
  try {
    objectUnderTest.myMethod(EVIL_ARGUMENT);
    fail("myMethod did not throw an Exception!");
  } catch (MyException e) {
    // ok!
    // check for properties of exception here, if desired
  }
}

JUnit 5 introduced yet another API change, but still uses annotations. The new @Test annotation is org.junit.jupiter.api.Test (the "old" JUnit 4 one was org.junit.Test), but it works pretty much the same as the JUnit 4 one.


I have a preference for JUnit 4 (Annotation approach) because I find it more flexible.

If you want to build test suite in JUnit 4, you have to create a class grouping all tests like this:

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


@RunWith(Suite.class)
@SuiteClasses({
    Test1.class,
    Test2.class,
    Test3.class,
    Test4.class
})public class TestSuite
{
 /* empty class */
}