JavaLib
 
Tester
 
Overview
Basic Types
User Types
Inexact Values
Sets
Iterable
Traversals
Maps
Random Choice
Range Check
Equivalence
ISame
Exceptions
Constructors
Methods
CheckFail
 
Sources
Downloads
 
TSRJ Home
TSRJ Local

Overview of the tester use

The tester package supports the design of tests for a program that consists of a collection of multiple classes and interfaces. A typical test suite consists of sample data for each class in the class hierarchy followed by the unit tests for every method in every class in the class hierarchy. The class where the tests are defined (typically called Examples class) represents the client for the defined class hierarchy, with the advantage of being defined in the same package, thus having access to the package-protected methods and fields.

The tests are designed to check whether the given actual value is the same as the expected value, comparing the objects for extensional equality. The comparison of two instances of objects in the same class is based on comparing the values of the corresponding fields. For complex data this comparison is replicated for each field that is an instance of another class.

The comparison of inexact values requires that the programmer invokes the checkInexact... variant of the test method and supplies the desired relative TOLERANCE. Otherwise, the exact test will fail if any field within the class contains an inexact value (i.e. a value of the type double or float) or their wrapper classes, and the comparison does not yield an exact true result (e.g. 5.0 == 5.0 succeeds while 5.0 == 10.0/2.0 fails).

Absolute tolerance is used when comparing an inexact value with a double or a float value that represents exact zero.

For data collections that implement the Iterable interface the elements of the structure are compared pairwise. This is done by default for the Java Collections Framework classes, but ihas to be invoked explicitly for the user-defined classes that implement the Iterable interface.

The design of tests for data collections that implement the Map interface again compares the values of the two collections.

There is a support for comparing inexact numerical values, wrapper classes, for testing whether a method invocation, or a constructor invocation threw the desired exception, and for tests where the programmer defines the meaning of equality for one class within the class hierarchy, or for any two objects.

Tests that determine whether the actual value is one of several possible values are also supported, as are tests for checking whether the actual value is within the given range of values, using either Comparable implementation for the given actual, or the given Comparator object.

The test report shows the number of test that have been performed, the number of tests that failed, and for every failed test it shows both the actual and the expected values, and provides a link to the place where the failed test is located. Additionally, the report includes a display of all data that have been defined as fields of the Examples class. The programmer can also access directly the code that produces a toString like representation of any object.

If the user implements toString method, both the user's result and the String-like representation of the object generated by the tester package is shown.

Defining the Tests

The following Examples class definition provides a simple preview of how the tests are written using the tester package.

import tester.*;

class Examples{
 Examples(){}
 
 Flight bos_phi = new Flight("BOS", "PHI",  8, 10);
 Flight phi_hst = new Flight("PHI", "HST", 11, 13);
 Flight hst_sfo = new Flight("HST", "SFO", 14, 15);
 Flight dfw_sfo = new Flight("DFW", "SFO", 14, 15);
 
 ILoF bos_sfo = new Flight("BOS", "SFO",  9, 14);
 ILoF bos_sfo_3 = new ConsLoF(this.bos_phi, 
                   new ConsLoF(this.phi_hst, this.hst_sfo));
 ILoF bos_sfo_err = new ConsLoF(this.bos_phi, 
                     new ConsLoF(this.phi_hst, this.dfw_sfo));
                     
 // test the method departsFrom for flight itinerary classes 
 boolean testDepartsFrom(Tester t){
     return 
          t.checkExpect(bos_phi.departsFrom(), "BOS")  &&
          t.checkExpect(phi_hst.departsFrom(), "PHI");
 }
               
 // test the method departsAfter for flight itinerary classes 
 void testDepartsAfter(Tester t){
     t.checkExpect(bos_phi.departsAfter(7), true);
     t.checkExpect(bos_phi.departsAfter(8), false);}
 
 // test the method connectsTo for flight itinerary classes 
 void testConnectsTo(Tester t){ 
     t.checkExpect(bos_phi.connectsTo(bos_sfo_3), this.phi_hst);
     t.checkExpect(bos_phi.connectsTo(bos_sfo), null);
 }
}

An instance of the Tester class invokes the test methods. This instance is a parameter for the method that invokes the tests. As long as the name of the method starts with the test and consumes one argument of the type Tester the tester package will evaluate the test cases defined within and record the results of the tests. The return type for the test method should be either boolean or void.

The imperative style where the return type for the test method is void is the preferred way of writing test cases, as it guarantees that every test will be performed.

The alternative style where the return type is boolean is provided to support the purely functional programming style used in the early parts of our curriculum. Here the result of the test method is a conjunction of several test cases. In this setting once a test case fails, the remaining test cases within this conjunction are not evaluated. We encourage the user to group together tests for every method, so that a failed result for one method does not affect the test results for other methods.

All test methods allow the user to supply an optional String argument that describes this test. When provided, this String is shown in the test report.

Reporting the Results

Once the tests have been run the tester package prints first the value of all fields defined in the Examples class. It then reports on the tests:

SimpleExamples:
---------------

   new SimpleExamples:1(
    this.hello =  "hello"
    this.world =  "world"
    this.n = 5)
------------------------------
Found 1 test method

Ran 3 tests.
All tests passed.

Test results: 
--------------

--- END OF TEST RESULTS ---
or, if errors have been detected the report prints both the actual and the expected value for that test and includes a link to the relevant line in the test suite:
SimpleExamples:
---------------

   new SimpleExamples:1(
    this.hello =  "hello"
    this.world =  "world"
    this.n = 5)
---------------
Found 1 test methods

Ran 4 tests.
1 test failed.

Test results: 
--------------

Error in test number 4
will fail
tester.ErrorReport: Error trace:
	at SimpleExamples.testStrings(SimpleExamples.java:12)

actual:                                 expected:
"hello"................................. "world"

--- END OF TEST RESULTS ---

last updated on Mon Apr 4 15:26:25 EDT 2011generated with DrRacket