JUnit is an open-source testing framework. It provides a way to write, organize, and run repeatable test.
For each class you want to test, you must create a file named ClassNameTest.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 ClassNameTest.java file must begin with the following line:
import junit.framework.*;
and must include a class declaration of the following form:
public class ClassNameTest 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 ClassNameTest.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 testMethodName to ClassNameTest.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 ClassNameTest.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 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); |