JUnit 3 vs JUnit 4 Comparison
Junit 3
Junit 4
comparison
There is a big change between JUnit 3.x and JUnit 4.x. JUnit 4 came with a lot of new features that introduce a lots of advantages.
Feature | JUnit 3.x | JUnit 4.x |
Compatibility | JDK 1.2+ | JDK 1.5+ is requered as is using annotations, generic, static import, features introduced in Java 5. |
Test method annotation | testXXX pattern for the method name |
@Test annotation |
Run before the first test method in the current class is invoked | None | @BeforeClass annotation |
Run after all the test methods in the current class have been run | None | @AfterClass annotation |
Run before each test method | override setUp() method |
@Before annotation |
run after each test method | override tearDown() method |
@After annotation |
How to ignore a test | Comment out, remove code or change the method name | @Ignore annotation |
Expected exception | catch exception assert success | @Test(expected = ArithmeticException.class) annotation |
How to test timeout | None | @Test(timeout = 1000) annotation |
static import of the assert classes | None | @Test(timeout = 1000) annotation |
How to define a test case
Here is a practical example of the same test case in both JUnit versions. To generate the test cases for each version a simple class will be used.
package com.admfactory.junit;
public class Stock {
private double value;
private long quantity;
public Stock(double value, long quantity) {
this.value = value;
this.quantity = quantity;
}
public void addStock(long q) {
this.quantity += q;
}
public void removeStock(long q) throws Exception {
if (q > this.quantity) {
throw new Exception("There is not enough quantity in the stock.");
}
this.quantity -= q;
}
public double getValue() {
return this.value;
}
public double getQuantity() {
return this.quantity;
}
public void setValue(double v) {
this.value = v;
}
public void clear() {
this.value = 0;
this.quantity = 0;
}
public double getTotalValue() {
return this.value * this.quantity;
}
}
The test cases will contain unit tests for the addStock and removeStock method with different values.
JUnit 3
package com.admfactory.junit;
import junit.framework.TestCase;
public class JUnit3StockUnitTest extends TestCase {
private Stock apples;
public void setUp() {
apples = new Stock(10d, 110);
}
public void testInitialTotalValue() {
assertTrue(apples.getTotalValue() == 1100);
}
public void testAddStock() {
apples.clear();
apples.addStock(10);
assertTrue(apples.getQuantity() == 10);
apples.addStock(12);
assertTrue(apples.getQuantity() == 22);
}
public void testRemoveStock() throws Exception {
apples.clear();
apples.addStock(10);
assertTrue(apples.getQuantity() == 10);
apples.removeStock(9);
assertTrue(apples.getQuantity() == 1);
}
public void testException() {
try {
apples.clear();
apples.addStock(10);
apples.removeStock(99);
fail("There is not enough in the store.");
} catch (Exception e) {
assertTrue(true);
}
}
public void tearDown() {
apples.clear();
}
}
As you can see the test cases methods starts with "test". setUp method is used to initialize the apples object and tearDown is used clear the stock.
JUnit 4
package com.admfactory.junit;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Before;
public class JUnit4StockUnitTest {
private Stock apples;
@Before
public void init() {
apples = new Stock(10d, 110);
}
@Test
public void initialTotalValue() {
assertTrue(apples.getTotalValue() == 1100);
}
@Test
public void addStock() {
apples.clear();
apples.addStock(10);
assertTrue(apples.getQuantity() == 10);
apples.addStock(12);
assertTrue(apples.getQuantity() == 22);
}
@Test
public void removeStock() throws Exception {
apples.clear();
apples.addStock(10);
assertTrue(apples.getQuantity() == 10);
apples.removeStock(9);
assertTrue(apples.getQuantity() == 1);
}
@Test(expected = Exception.class)
public void exception() throws Exception {
apples.clear();
apples.addStock(10);
apples.removeStock(99);
}
@After
public void clean() {
apples.clear();
}
}
Comparing the examples the test cases uses the annotation @Test
, the init method uses @Before
annotation, the end method uses @After
annotation. Also, a big difference is how Exceptions are checked: JUnit 3.x uses try catch block and JUnit 4.x uses annotation property expected.