===== JUnit v3 =====
==== Introduction ====
JUnit is an open-source testing framework. It provides a way to write, organize, and run repeatable test.
==== Creating Test Classes ====
For each class you want to test, you must create a file named //ClassName//Test.java where //ClassName// denotes the name of the class being tested. So, for example, if you want to test the class named ''%%Atom%%'' you must create a file named ''%%AtomTest.java%%''.
The //ClassName//Test.java file must begin with the following line:
import junit.framework.*;
and must include a class declaration of the following form:
| public class //ClassName//Test extends TestCase |
So, continuing with the example above, ''%%AtomTest.java%%'' would initially contain the following:
import junit.framework.*;
public class AtomTest extends TestCase
{
}
(Note: Don't worry if you haven't studied specialization and, so, don't understand the meaning of ''%%extends TestCase%%''. It doesn't matter for what follows.)
The file //ClassName//Test.java must contain (at least) one method for every method in //ClassName//. In particular, if there is a method named //MethodName// in //ClassName// then you must add a ''%%public void%%'' method named test//MethodName// to //ClassName//Test.java. So, still continuing with the example above, if the ''%%Atom%%'' class contains a ''%%public int getAtomicNumber()%%'' method, then ''%%AtomTest.java%%'' must implement the following method:
/**
* Unit tests for the getAtomicNumber() method
*/
public void testGetAtomicNumber()
{
}
Note the use of "camel case" in the naming of this method. Though the 'g' in ''%%getAtomicNumber()%%'' is lowercase, the 'G' in ''%%testGetAtomicNumber%%'' is uppercase.
The body of the methods in the //ClassName//Test.java must contain the test cases for the corresponding methods in the //ClassName// class. These test cases often involve some "setup" code and a call to the ''%%Assert.assertEquals()%%'' method. So, for example, the ''%%getAtomicNumber%%'' method in the ''%%Atom%%'' class is supposed to return the atomic number of the calling ''%%Atom%%'' object. To partially test this method one might implement the ''%%testGetAtomicNumber()%%'' method in the ''%%AtomTest%%'' class as follows:
/**
* Unit tests for the getAtomicNumber() method
*/
public void testGetAtomicNumber()
{
Atom o;
o = new Atom("O", 8, 16);
Assert.assertEquals("Oxygen", 8, o.getAtomicNumber());
}
In the "setup" portion, this method creates an ''%%Atom%%'' objects (for oxygen). It then calls the ''%%Assert.assertEquals()%%'' method to tell jUnit to do some testing. This particular version of the ''%%Assert.assertEquals()%%'' method is passed three parameters and has the following syntax:
| Assert.assertEquals(//Description//, //ExpectedValue//, //ActualValue//); |
The //Description// is a human-readable ''%%String%%'' that provides information that enables the tester to understand the test in the event that the code fails the test. The //ExpectedValue// contains the correct value (i.e., the value that the tester expects if the method named //MethodName// in //ClassName// is working correctly. The //ActualValue// contains the value that was actually generated by the method named //MethodName// in //ClassName//.
In the example above, the ''%%getAtomicNumber()%%'' method in the ''%%Atom%%'' class is being tested. A call to ''%%o.getAtomicNumber()%%'' should return ''%%8%%''.
As another example, suppose the ''%%Atom%%'' class contains a ''%%public boolean equals(Atom other)%%'' method, then ''%%AtomTest.java%%'' must implement the following method:
/**
* Unit tests for the equals(Atom) method
*/
public void testEquals()
{
}
Note that, even though the ''%%equals()%%'' method in the ''%%Atom%%'' class is passed an ''%%Atom%%'' object and returns a ''%%boolean%%'', the ''%%testEquals()%%'' method in ''%%AtomTest.java%%'' has no parameters an does not return anything.
The ''%%equals()%%'' method in the ''%%Atom%%'' class is supposed to compare the calling ''%%Atom%%'' object with the given ''%%Atom%%'' object and return ''%%true%%'' if the two have the same attributes and ''%%false%%'' otherwise. To partially test the ''%%equals()%%'' method, one might implement the ''%%testEquals()%%'' method in the ''%%AtomTest%%'' class as follows:
/**
* Unit tests for the equals(Atom) method
*/
public void testEquals()
{
Atom h, o;
h = new Atom("H", 1, 1);
o = new Atom("O", 8, 16);
Assert.assertEquals("Compare H and O", false, h.equals(o));
}
The ''%%equals(Atom)%%'' method in the ''%%Atom%%'' class is being tested. A call to ''%%h.equals(o)%%'' should return ''%%false%%''.
==== The Assert.assertEquals() Method ====
The ''%%Assert.assertEquals()%%'' method can be used to compare the expected and actual values of a wide variety of different types. In the examples above it is used to compare ''%%int%%'' values and ''%%boolean%%'' values. It can also be used to compare ''%%String%%'' objects.
When using ''%%Assert.assertEquals()%%'' to compare floating point numbers (e.g., ''%%double%%'' values), one must be careful. In general, one should not use the ''%%==%%'' operator with ''%%double%%'' values because of the less-than-perfect precision of operations on ''%%double%%'' values. In JUnit, the implication of this is that one should check to see if ''%%double%%'' values are within a tolerance value of each other. Hence, when comparing ''%%double%%'' values one should use the following:
| Assert.assertEquals(//Description//, //ExpectedValue//, //ActualValue//, //tolerance//); |