===== 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//); |