Writing Unit Tests with JUnit

What and Why?

JUnit is a testing framework aimed at making unit testing easy by simplifying the writing of test cases and by providing automated running of tests and test suites.  Most programmers use only informal test methods.We think about the various cases to test for and we perform them manually by interacting with the unit/module.The problem with this approach is that it is very tedious to do and is also very repetitive. Students generally don’t like to test because of the boring and tedious repetition.By automating the process, testing becomes less painful, more reliable, and less time consuming.Furthermore, by using a framework, the process of writing the test case is as easy as following a recipe.

Setting Up your Environment

Omit this section if you are using NetBeans or BlueJ IDE.

Download the version 3.8 of JUnit at www.junit.org
Extract it to a location, say C:\
You should now have a directory like C:\junit3.8
Make your classpath variable point to junit.jar, for example:
set classpath=%classpath%;C:\junit3.8\junit.jar;.

Writing a Test Case

Let's write unit tests for the Rationals class from the Lewis and Loftus text. You can read the typical, cumbersome approach to testing in his RationalNumbers class on page 196.

  1. Download and compile Rational.java.
  2. Create a new java source file for the unit tests, RationalTest.java
  3. import junit.framework.*; 

  4. Implement a class derived from TestCase, a base class provided by JUnit.
        public class RationalTest extends TestCase
  5. Be sure the test class belongs to the same package as that of the unit you wish to test*
  6. Create a constructor that takes a string and passes it to super
       public RationalTest (String name)
        super (name);
  7. Override the setUp method
    Instantiate any objects you wish to test here, these objects are referred to as your fixture. JUnit will automatically setup a fresh fixture for you using this method prior to running each test method!
         protected void setUp()
         r1 = new Rational(6, 8);
         r2 = new Rational(1, 3);
  8. Implement a parameter-less method for each aspect of the unit you wish to test.
    The general strategy is to perform some action on the variables in your fixture using the methods of the class under test, then verify the results using the JUnit assertTrue() method.

     public void testEquals()

  9.  {
      assertTrue(r1.equals(new Rational(3, 4)));
      assertEquals(r1, new Rational(3, 4));
     Note: assertEquals() requires that valueA, valueB have an overriden equals method.All Java classes are derived from Object and have a default equals method that compares object addresses and not object values, hence the need to override the equals method.

    If you conform to the simple convention that your method names begin with ‘test’, JUnit will then automatically execute all the methods as a suite.  Alternatively, you can set up your own suite (see documentation).
Here is the completed RationalTest class.

Running the Test Suite

JUnit provides a TestRunner tool to perform the actual run of the test. The TestRunner classes take a Test class and runs all its methods. It provides feedback via the asserts. TestRunner will report how many tests were successful, how many failed, and how long the tests took. The asserts will tell you where the error occurred and implicitly what the error was. If all the tests pass, you get a pretty green bar, otherwise you get a red bar.

To run the TestRunner:

java junit.swingui.TestRunner <your test class>
for example: java junit.swingui.TestRunner RationalTest
You can either specify the test class at the commandline or load it from within the GUI. The [your test class] parameter becomes optional.

There is also a text version of the TestRunner which is preferable for use in batch testing. It requires a test suite method.

Need more help? The junit download contains a docs folder with more documentation.
Another helpful reference is the Assert class javadocs.

CPE 308 home

* This will give your test case access to package private members.