JUnit

JUnit is unit testing framework for the Java programming language. It allows you to easily verify the individual unit of source code through assertions.

Execution order of JUnit's annotations

/**
 * Show the execution order of each annotations.
 * Given this test, the methods will execute in the following order:
 * oneTimeSetUp()
 * setUp()
 * testMyFunction1()
 * tearDown()
 * setUp()
 * testMyFunction2()
 * tearDown()
 * oneTimeTearDown()
 * 
 * **NOTE**: JUnit doesn't guarantee the execution order of the test functions(@Test).
 * 
 * @author: Xuan Ngo
 */
import org.junit.*;
 
public class JUnitCheatSheet
{
 
  @BeforeClass
  public static void oneTimeSetUp()
  {
    // one-time initialization code
    System.out.println("oneTimeSetUp()");
  }
 
  @AfterClass
  public static void oneTimeTearDown()
  {
    // one-time cleanup code
    System.out.println("oneTimeTearDown()");
  }
 
  @Before
  public void setUp()
  {
    // Run before every test methods.
    System.out.println("setUp()");
  }
 
  @After
  public void tearDown()
  {
    // Run after every test methods.
    System.out.println("tearDown()");    
  }
 
  @Test
  public void testMyFunction1()
  {
    // Test MyFunction 1.
    System.out.println("testMyFunction1()");
  }
 
  @Test
  public void testMyFunction2()
  {
    // Test MyFunction 2.
    System.out.println("testMyFunction2()");
  }
}

Parameterized Tests

Sometimes you want to use a generic test method to test with different sets of values. But if you use a loop to do that, then the whole method will fail if 1 of the set of values fails. As a result, it is not helpful as you don't know which specific set of values failed. JUnit report will only show that the generic test method as a whole failed. But if you are writing 1 test method per set of values, then there is a lot of codes, which is not efficient and practical.

Fortunately, JUnit has a feature called parameterized test which will replicate the same test method for each set of values. Consequently, if 1 of the set of values fails, JUnit will show you which set failed.

Below is a simple example of a parameterized test.

/**
 * Show how parameterized test is done in JUnit.
 * 1)Put the annotation @RunWith for the Test Class
 * 2)Must have a public static method that returns a Collection of data.
 * 3)You will also need a public constructor that uses the parameters.
 *
 * This parameterized test is intended to fail on the 3rd data set to show you
 *  a mixture of pass and failed data set.
 * @Author: Xuan Ngo
 */
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
 
 
import java.util.Arrays;
import java.util.Collection;
 
@RunWith(Parameterized.class)
public class ParameterizedTest
{
  private int m_iA = 0;
  private int m_iB = 0;
  private int m_iExpected = 0;
 
  // Needs a public static method (here the function name is irrelevant) that
  // returns a Collection and is annotated with @Parameters.
  @Parameters
  public static Collection data()
  {
    return Arrays.asList(new Object[][]
                            {
                              // {iA, iB, iExpected},
                              { 0, 0, 0 }, 
                              { 1, 1, 2 }, 
                              { 2, 4, 5 }, // will fail.
                              { 2, 4, 6 }, });
  }
 
  /*
    // Another way to implement Collection data()    
    @Parameters
    public static ArrayList<Integer[]> data()
    {
      ArrayList<Integer[]> oArrayList = new ArrayList<Integer[]>();
      // {iA, iB, iExpected},
      oArrayList.add(new Integer[]{1,1,2});
      oArrayList.add(new Integer[]{9,5,14});
      oArrayList.add(new Integer[]{5,5,11});
 
      return oArrayList;
    }
  */
 
  // Constructor: Make sure that argument parameters are in the
  // same order as your Collection data.
  public ParameterizedTest(int iA, int iB, int iExpected)
  {
    this.m_iA = iA;
    this.m_iB = iB;
    this.m_iExpected = iExpected;
  }
 
  @Test
  public void TestingExclusivelyGetSum()
  {
    final int iResult = this.getSum(this.m_iA, this.m_iB);
    assertEquals(this.m_iExpected, iResult);
  }
 
  // To test getSum() function, I put it here so
  // that this test class is self completed.
  public int getSum(final int iA, final int iB)
  {
    return iA + iB;
  }
}