Augustana Faculty logo and wordmark


COMPUTING SCIENCE 220
Software Engineering I


Lab Exercise
JUnit with Eclipse



Objectives

Setup

If you wish to do this at home, you will need to install JUnit:

. JUnit home page

The new versions of Eclipse include JUnit already, so you may not need to install JUnit independently.

Creating a Simple Test using JUnit in Eclipse

The first exercise of this lab will demonstrate how to implement a simple test. This test is from the JUnit FAQ that accompanies the JUnit package, but the instructions that follow are specific to using JUnit within the Eclipse IDE.

  1. Create a new Eclipse project named, for example, JUnitTest.

  2. Select the JUnit Test Case wizard by selecting File - New from the menu bar (or by clicking on the leftmost icon on the icon toolbar), then, under Other, select Java, then JUnit, and finally JUnit Test Case. A JUnit Test Case window should pop up. It should indicate that the source folder is JUnitTest (or whatever you named the new project) and that the superclass is junit.framework.TestCase.

  3. In the JUnit Test Case window, provide a package name such as testJUnit, a class name such as SimpleTest, and select method stubs for a main method with a TestRunner statement for a "text ui", and a constructor. Click the Finish button.

  4. "Write a test method to assert expected results on the object under test" [from the JUnit FAQ]:

        public void testEmptyCollection() 
        {
            Collection<String> collection = new ArrayList<String>();
            assertTrue(collection.isEmpty());
        }
    

    Eclipse should highlight Collection and ArrayList as being in error, because we have not imported these classes. Select Source - Organize Imports to have Eclipse add the appropriate import statements to the top of your Java program.

  5. With the file SimpleTest.java highlighted in the Package Explorer, select Run As (either by selecting Run - Run As from the menu bar or by clicking near the small arrow on the icon that looks like a "Play" button on a CD player) and select JUnit Test. This should run the simple test and show a graphical JUnit test runner in the left-hand frame of Eclipse (in place of the package explorer). The test runner should be displaying a green bar, indicating that the test was successful.

  6. Let's try adding another test [also from the JUnit FAQ]:

        public void testCollectionAdd() 
        {
            Collection<String> collection = new ArrayList<String>();
            assertEquals(0, collection.size());
            collection.add("itemA");
            assertEquals(1, collection.size());
            collection.add("itemB");
            assertEquals(2, collection.size());
        }
    

    This time, try clicking the "Rerun Last Test" icon in the JUnit test runner — it looks like a "Play" button with a right-pointing yellow arrow below it — to run the test case again. This time, the JUnit test runner should report "Runs: 2/2" to indicate that two test methods were executed.

  7. Try making one of the test cases fail. For example, you could change one of the numbers in an assertEquals statement, then rerun the tests. You should see a red bar instead of a green one. Look in the "Failure Trace" area for a line beginning "at testJUnit.SimpleTest" to see which test failed. If you scroll to the right, you should see that the line ends with "testCollectionAdd(SimpleTest.java:xx)", where the "xx" will actually be the line number of the test that failed.

  8. Now change another number in the testCollectionAdd method so that two of the assertions in that method should fail. Rerun the test. What happens?

Using a JUnit Test Fixture

Because JUnit will only report the first failed assertion from a given method, we normally create a separate method to contain each assertion (unless the assertions are strongly related, as they are in the testCollectionAdd method). The following code shows what would result if we were to separate the assertions in the testCollectionAdd method (even though they are strongly related — we just need a simple demonstration of how we could separate them if we wanted to).

    public void testCollectionAdd0() 
    {
        Collection<String> collection = new ArrayList<String>();
        assertEquals(0, collection.size());
    }

    public void testCollectionAdd1() 
    {
        Collection<String> collection = new ArrayList<String>();
        collection.add("itemA");
        assertEquals(1, collection.size());
    }

    public void testCollectionAdd2() 
    {
        Collection<String> collection = new ArrayList<String>();
        collection.add("itemA");
        collection.add("itemB");
        assertEquals(2, collection.size());
    }

Now if you were to change the numbers in two different assertEquals statements and then rerun the tests, JUnit would report two failures instead of one. Note that it is also easier to tell which test failed, because each of the names of the methods reported in the "Failures" area of the JUnit test runner correspond to a single test.

However, we now have four repetitions of the line

    Collection<String> collection = new ArrayList<String>();

because the same setup — here, the creation of a collection object — is needed by each test.

This redundancy can be reduced by using a test fixture. According to the JUnit FAQ:

A test fixture is useful if you have two or more tests for a common set of objects. Using a test fixture avoids duplicating the test code necessary to initialize and cleanup those common objects for each test.

A test fixture is just like a test case, but adds a setUp and (optionally) tearDown method to do whatever initialization and cleanup is necessary before and after executing each test. (Note that the initialization is performed prior to each test, so that each test is executed in a new test fixture. The use of a setUp method only saves on the writing of redundant code, not on its execution during testing.)

Revise your tests by factoring out the common initialization statement and putting it in a setUp method. (No tearDown method is needed in this case.)

  1. Add an attribute to the class so that a collection object can be created in a setUp method but accessed by the various test methods:

        Collection<String> collection
  2. Add a setUp method, as follows:

        protected void setUp() 
        {
            collection = new ArrayList<String>();
        }
    
  3. Remove the object initialization statement from each test:

        public void testEmptyCollection() 
        {
            assertTrue(collection.isEmpty());
        }
    
        public void testCollectionAdd0() 
        {
            assertEquals(0, collection.size());
        }
    
        public void testCollectionAdd1() 
        {
            collection.add("itemA");
            assertEquals(1, collection.size());
        }
    
        public void testCollectionAdd2() 
        {
            collection.add("itemA");
            collection.add("itemB");
            assertEquals(2, collection.size());
        }
    

Resources

.Unit Testing in Eclipse Using JUnit — This is a more complete introduction to the use of JUnit in Eclipse, created by Laurie Williams and her team at North Carolina State University. It includes an exercise based on an application that is known to have bugs in it; students are supposed to use unit testing to identify and fix 5 known bugs in the code, based on the user stories provided as requirements documentation for the application.

Copyright © 2005, 2007 Jonathan Mohr