- Junit 3 vs Junit 4 Overview
- 1. JDK Required?
- 2. JPackage Structure
- 3. How to define a text case? Junit 3 VS Junit 4
- 4. Annotations and new features added (Junit 3 VS Junit 4).
- 5. New JUnit runners
- 6. Static imports, New assertions and assumptions.
- 7. Exception testing (Difference between Junit 3 and Junit 4)
- 8. Ignoring a test
- 9. Timeout testing
- 10. Test suites
- 11. Parameterized tests
- Conclusion
Junit 3 vs Junit 4 Overview
Junit 4 is the next series of Junit 3 and introduced lot of features. It has been compatible with most tools for a while. We will compare junit 3 and junit 4 to give the difference from 11 aspects.
1. JDK Required?
JUnit 4 requires Java 5 or higher, it uses a lot from Java 5 annotations, generics, and static import features. The JUnit 3.x version can work with JDK 1.2+ and any higher versions.
2. JPackage Structure
JUnit 4 is built on the idea of backward compatibility, it leaves the old package org.junit
. For all JUnit 4.x new features, they were added to a new package junit.framework
.
3. How to define a text case? Junit 3 VS Junit 4
In the new version of JUnit, test classes are no longer required to extend junit.framework.TestCase
class, test names are no longer need required to follow the testXXX pattern. Instead, in Junit4.x, any public classes with a zero-argument public constructor can act as a test class, any methods which need consider as a test method should be annotated with the @Test
annotation.
A typical test case in Junit 3.x
import junit.framework.Assert; import junit.framework.TestCase; public class TournamentTest extends TestCase{ Tournament tournament; public void setUp() throws Exception { System.out.println("Setting up ..."); tournament = new Tournament(100, 60); } public void tearDown() throws Exception { System.out.println("Tearing down ..."); tournament = null; } public void testGetBestTeam() { Assert.assertNotNull(tournament); Team team = tournament.getBestTeam(); Assert.assertNotNull(team); Assert.assertEquals(team.getName(), "Test1"); } }
A typical test case in Junit 4.x
import junit.framework.Assert; import org.junit.After; import org.junit.Before; import org.junit.Test; public class TournamentTest { Tournament tournament; @Before public void init() throws Exception { System.out.println("Setting up ..."); tournament = new Tournament(100, 60); } @After public void destroy() throws Exception { System.out.println("Tearing down ..."); tournament = null; } @Test public void testGetBestTeam() { Assert.assertNotNull(tournament); Team team = tournament.getBestTeam(); Assert.assertNotNull(team); Assert.assertEquals(team.getName(), "Test1"); } }
4. Annotations and new features added (Junit 3 VS Junit 4).
In JUnit 3.x, we have to override the setUp()
and tearDown()
methods. But in,JUnit 4.x, it is based on annotations, it would not require to extend any particular methods, use @Before
and @After
to annotate the methods which needs execution right before/after each of the tests. Another new feature that JUnit 4.x offers is the @BeforeClass and @AfterClass annotations. the methods with this annotations are executed before/after a whole set of tests.
Feature | JUnit 3.x | JUnit 4.x |
test annotation | testXXX pattern | @Test |
run before the first test method in the current class is invoked | None | @BeforeClass |
run after all the test methods in the current class have been run | None | @AfterClass |
run before each test method | override setUp() | @Before |
run after each test method | override tearDown() | @After |
ignore test | Comment out or remove code | @ignore |
expected exception | catch exception assert success | @Test(expected = ArithmeticException.class) |
timeout | None | @Test(timeout = 1000) |
5. New JUnit runners
The 3.x version of JUnit comes with Swing and AWT test runners that are no longer part of the JUnit distribution. The test runner façade that you can use to start your tests from the console is now called org.junit.JUnitCore.
6. Static imports, New assertions and assumptions.
Junit3.x lacks the ability of comparing equality of arrays and assumptions. In Junit 4, it introduced more interesting and valuable assert method (see below), you can also easily import all assertion methods or any particular one.
assertEquals(Object[] expected, Object[] actual)
assertEquals(String message, Object[] expected, Object[] actual)
assumeThat(T actual, org.hamcrest.Matcher<T> matcher)
7. Exception testing (Difference between Junit 3 and Junit 4)
in Junit 4.x, @expected was added to test exceptional situations in your code.
Junit 3.x
public void testGetElement() { try { (new ArrayList()).get(0); fail("The test should have failed"); } catch (NullPointerException e) { assertTrue("Sanity check", true); } }
Junit 4.x
@Test(expected = IndexOutOfBoundsException.class) public void testGetElement() { (new ArrayList()).get(0); }
8. Ignoring a test
In the 3.x version of JUnit, the only way to do that is to comment the whole test method or rename the method. This is significantly improved in JUnit 4.x, by the introduction of the @Ignore
annotation.
9. Timeout testing
Another parameter you can add to the @Test annotation is the timeout parameter.This feature was also missing in the “old” JUnit. With this parameter, you can specify a value in milliseconds that you expect to be the upper limit of the time you spend executing your test.
10. Test suites
The old way of constructing sets of your tests involved writing a suite() method and manually inserting all the tests that you want to be present in the suite. Because the new version of JUnit is annotation oriented, it seems somehow logical that the construction of suites is also done by means of annotation. Further, the suite construction is done not by one annotation but by two annotations: the @RunWith and @Suite Classes annotations. The first annotation lets you define test runners that you can use to run your tests. The @RunWith annotation accepts a parameter called value, where you need to specify the test runner to run your suite: Suite.class. This test runner is included with JUnit, along with some other runners. But in this annotation you can also specify a custom runner. The second annotation declares all the tests that you want to include in the suite. You list the classes that hold your tests in the value parameter of the @SuiteClasses annotation.
11. Parameterized tests
As you saw, in Junit 4.x, the @RunWith annotation lets you define a test runner to use. The Suite test runner that we already presented lets you run your test cases in a suite. Another test runner that’s bundled with the JUnit distribution is the Parameterized test runner. This test runner lets you run the same tests with different input test data.
Conclusion
JUnit 4 has lots of advantages over 3.x, most tools have been compatible with 4.x for a while now. I think we have no reason that stick to 3.x.