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 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 no longer need to extend junit.framework.TestCase class, test names no longer need to follow the testXXX pattern. Instead, in Junit4.x, any public class with a zero-argument public constructor can act as a test class, any method that you want to be considered a test method should be annotated with the @Test annotation.
A typical test case in Junit 3.x
TournamentTest.java
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 teanDown() 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
TournamentTest.java
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 used to override the setUp() and tearDown() methods when we extended the junit.framework.TestCase class. Instead, JUnit 4.x is based on annotations, we don’t need extend any methods, just use @Before and @After annotate the methods which will be executed right before/after each of the tests gets executed. one new feature that JUnit 4.x offers is an option with 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.
With Java’s static imports, you can write the code to directly import all assertions or special one, in Junit3.x, they lack any method to compare equality of arrays and assumptions. so the following methods were introduced.
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
Test case: testGetElement
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.
Pingback: Junit Tutorial and Example
Good article but there is a mistake in the table comparing JUnit 3.x with 4.x. In JUnit 3.x, the overrided setUp() method should be run before each test method, and the overried tearDown() method should be run after each test method. Please refer to Appendix A. Differences between JUnit 3 and JUnit 4 of the book “Junit in Action 2nd Edition”.
Right, setUp/tearDown is run before/after each method, thanks for indicating and just have corrected it.
It’s correct now. Thanks.