Labels

Thursday, May 12, 2016

[Java] JUnit basics

A small introduction to JUnit in Eclipse

There is a simple way to do unit test for Java in Eclipse, that is JUnit. The first time that I used JUnit, I was amazed by its simplicity and efficiency. As part of the assignment of the project Fil Rough in the module INF 301, I've wrote test cases to see whether units of the back-end of a betting system works well. At the same time, our professor also use the JUnit as a way to measure the results our solution. Before I learned how to use JUnit, writing a main method after the class that I want to test was really a repetitive and boring task. However, with the help of JUnit, I can write all the test case in a same place, what's more, I can have more control over the code that I've written.

JUnit in Eclipse

Firstly, to use JUnit, JUnit packages needs to be loaded, so
import org.junit
needs to be written as first line in our test class. Below is a concrete example of how we use JUnit to do unit test.
import java.util.LinkedList;

import org.junit.*;

public class MyLinkedListTester {

    private static final int LONG_LIST_LENGTH =10;
    MyLinkedList<Integer> emptyList;
    MyLinkedList<Integer> longerList;

    /**
     * run every time before each test
     */
    @Before
    public void setUp() throws Exception {
        // Initialize 2 list for the following test
        emptyList = new MyLinkedList<Integer>();
        longerList = new MyLinkedList<Integer>();
        for (int i = 0; i < LONG_LIST_LENGTH; i++)
        {
            longerList.add(i);
        }
    }

    /**
     * run only one time before test
     */
    @BeforeClass
    public void setUpClass()
    {
    }

    /** Test if the get method is working correctly.
     */
    /*You should not need to add much to this method.
     * We provide it as an example of a thorough test. */
    @Test
    public void testGet()
    {
        //test empty list, get should throw an exception
        try {
            emptyList.get(0);
            fail("Check out of bounds");
            //System.out.println("Check out of bounds" + " - failed");
        }
        // test longer list contents
        for(int i = 0; i<LONG_LIST_LENGTH; i++ ) {
            assertEquals("Check "+i+ " element", (Integer)i, longerList.get(i));
        }
    }

    /** Test removing an element from the list.
     * We've included the example from the concept challenge.
     * You will want to add more tests.  */
    @Test
    public void testRemove()
    {
    }

    /** Test adding an element into the end of the list, specifically
     *  public boolean add(E element)
     * */
    @Test
    public void testAddEnd()
    {
    }

    /** Test the size of the list */
    @Test
    public void testSize()
    {
    }

    /** Test adding an element into the list at a specified index,
     * specifically:
     * public void add(int index, E element)
     * */
    @Test
    public void testAddAtIndex()
    {
    }

    /** Test setting an element in the list */
    @Test
    public void testSet()
    {
    }

    /**
     * run every time after each test
     */
    @After
    public void tearDown()
    {
    }

    /**
     * run every only one time after test
     */
    @AfterClass
    public void tearDownClass()
    {
    }

}
For the basic use of JUnit, 5 annotations needs to be learned, namely @Before, @BeforeClass, @test, @After and @AfterClass. Here are the signatures
@Before
public void setUp() throws Exception
{
    // is run before each test to initialize variables and objects
}

@BeforeClass
public static void setUpBeforeClass() throws Exception
{
    // is run only once before the class to initialize objects
}

@test
public void test<feature>()
{
    /* <feature> denotes a feature that we want to test
    * if we want to test Remove method of the class
    * the method name can be testRemove()
    */

}

@After
public void tearDown() throws Exception
{
    /* This method can be useful if your test constructed something which needs
    * to be properly torn down, for example, the database
    */
}

@AfterClass
public static void tearDownAfterClass() throws Exception
{
    /* This method can be useful if your setUpClass() method constructed something
    *  which needs to be properly torn down, for example, the database
    */
}
We notice that @Before, @BeforeClass, @After and @AfterClass are help method that help us to setup and clean the test environment, the most important is @test, there are serveral ways to test a method of a class, for the basic use of JUnit, we need at least know the following 2 method.

To test corner cases

we can test corner cases by using fail() method, here the method that we want to test is emptyList.get(0);. As we know, we can not get element from an empty list, emptyList.get(0); should throw an exception. However, if no exceptions are thrown during this method, fail() method would be called to let us know the emptyList.get(0); must has something wrong .
try {
            emptyList.get(0);
            fail("Check out of bounds");
            //System.out.println("Check out of bounds" + " - failed");
        }
        catch (IndexOutOfBoundsException e) {
            //System.out.println("Check out of bounds" + " - passed");

To test common cases

we can use assertEquals() to test common cases, assertEquals() takes 3 input, the first is a Sting, test message can be written here to let us know which test is runned, the second is expected value, the third is actual value that we get from the method that we want to test.
// test longer list contents
        for(int i = 0; i<LONG_LIST_LENGTH; i++ ) {
            assertEquals("Check "+i+ " element", (Integer)i, longerList.get(i));
        }
So in this way, we can test if the output of a certain method meets our expectation, if the expected value doesn't equal to the actual value, we can get a failure from JUnit control board. The signature of assertEquals() are shown below
assertEquals(java.lang.String message, long expected, long actual)
                Asserts that two longs are equal

No comments:

Post a Comment