Change history

April 10
Changed to use JUnit 3.5 rather than 3.4.

CIS422 Software Methodology

Writing Test Suites With JUnit

 

Summary 

This article demonstrates how to write and run test suites using the JUnit testing framework as required for the CIS422 programming assignments. 

 

What is JUnit?

JUnit is a small testing framework written in Java by Kent Beck and Erich Gamma. Beck and Gamma are well-known as two of the founders of the Software Patterns movement. In depth information on JUnit can be found at the JUnit home page at http://www.junit.org/.

 

How do you use JUnit?

JUnit is a collection of Java classes. In order to use it you first have to download and install it.

Step 1: Downloading and installing JUnit3.5

The latest version of JUnit can be found at http://www.junit.org/. Download it and follow the installation steps below:

 

  1. unzip the junit.zip file to a directory of your choice.
    In the following we will assume the install directory to be /nfs/home/users/hamlet/junit3.5.
  2. add junit.jar to the CLASSPATH by editing your .chrc file and appending the path to junit.jar to your CLASSPATH variable:

§         (if you already have a CLASSPATH variable defined in your .cshrc file, then include this line right after it, assuming your previous CLASSPATH ends with a ':')

    setenv CLASSPATH=${CLASSPATH} /nfs/home/users/hamlet/junit3.5/junit.jar:/nfs/home/users/hamlet/junit3.5

               (if you don't have a CLASSPATH variable defined in your .cshrc file, then include this line)

                  setenv CLASSPATH=.:/nfs/home/users/lnguyen/junit3.5/junit.jar:/nfs/home/users/lnguyen/junit3.5

In addition, the .cshrc file has to be "run" before the CLASSPATH variable will acutally be changed in your shell environment. The easiest way to do this is just to open a new console. You can check the current value of your classpath by typing

echo $CLASSPATH

The CLASSPATH variable is used by Java to help it find where classes are located; it determines where Java looks for packages and classes when it needs to load them. If you're getting "class not found" or "package not found on import" tupe of errors, then your classpath is not set correctly.

  1. test the installation by using the graphical TestRunner tool to run the tests that come with this release..

§         Go to the install directory: cd /nfs/users/hamlet/junit3.5

§         type: java junit.ui.TestRunner junit.samples.AllTests

§         All the tests should pass OK and you should see the following window:

 

 

If you have problems setting up your classpath consult http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/classpath.html.

 

 

Step 2: Writing a Test Suite with JUnit

Using JUnit to test Java programs is very easy.

 

Let’s assume you want to test the implementation of a class named MyBoard which implements the BoardI interface (the source code is available here).

In order to test whether our implementation of MyBoard is correct or not we write a test suite that contains a number of test cases. Each test case verifies a particular use of the class against the expected behavior. For example, we might want to verify that MyBoard actually throws a SquareOutOfBounds when we try to place a PlayingPiece on an invalid square. Or, we might want to verify that when we place a piece on the board with setPiece(x, y) that we get the same piece back if we call getPiece(x, y). The aim, as is customary in software testing, is not to show that your program works fine, but to try and find out where it breaks.

 

To write a test suite with several test cases requires implementing a class derived from the class junit.framework.TestCase. Each method of this class defines a test case that exercises a different aspect of the tested software. Interaction with the JUnit framework is achieved through assertions, which are method calls that check (assert) that given conditions hold at specified points in the test execution.

IMPORTANT: The names of your test functions should be prefaced with "test", e.g., "test1()" or "testFoo()".

 

Coming back to our example we will now define a test suite for our MyBoard class.

 

// file MyBoard_TestSuite.java
import junit.framework.*;

public class MyBoard_TestSuite extends TestCase {
  // Test normal operation of setPiece()
  //
  // IMPORTANT: the names of your test functions should be prefaced with "test"
  public void testSetPiece() {
	PlayerI player1 = new MyPlayer();
	PlayerI player2 = new MyPlayer();
	
	BoardI board = new MyBoard(10);  // 10 by 10 board

	try {
	    // place some pieces on the board
	    PlayingPiece p1 = new PlayingPiece("black", player1);
	    board.setPiece(p1, 0, 1);
	    PlayingPiece p2 = new PlayingPiece("white", player2);
	    board.setPiece(p2, 0, 2);
	    
	    // retrieve pieces and make sure they're the same
	    assert(board.getPiece(0, 1) == p1);
	    assert(board.getPiece(0, 2) == p2);

	    // make sure different pieces are indeed different
	    assert(board.getPiece(0, 1) != board.getPiece(0, 2));
	} catch (SquareOutOfBoundsException e) {
	    assert(false);  // test failed
	}
    }
    
    // We now define three methods which are used internally by the 
    // JUnit test framework. It's not really important for our purposes 
    // to understand what is going on here, but you can consult the
    // JUnit documentation if you want to know. Every test suite that
    // you write should contain similar code, however (substituting the
    // name of your class for MyBoard).
    
    public MyBoard_TestSuite (String name) {
        super(name);
    }
 
    public static Test suite() {
        TestSuite suite = new TestSuite(MyBoard_TestSuite.class);
        return suite;
    }
 
    public static void main(String args[]) {
        String[] testName = {MyBoard_TestSuite.class.getName()};
        // junit.textui.TestRunner.main(testName);
	junit.swingui.TestRunner.main(testName);
    }
}

After we have defined a test suite we want to see whether our test cases succeed or fail. We do that by compiling and running our test suite as follows:

 

            javac MyBoard__TestSuite.java

java MyBoard_TestSuite

 

 

If all test cases succeed we should see a green horizontal line in the JUnit window:

 

 

If some of the test cases fail we should see a red horizontal line in the JUnit window. In that case JUnit tells us which test cases failed:

 

 

Of course we want all test cases to succeed so if a test case fails we need to go back to our implementation and correct our mistake.