Writing Unit Tests

The framework class JadeTestCase provides assertion methods that you can use in your unit test methods. The example used in the following sections to illustrate how unit tests are written is a system that enables a user to carry out arithmetical calculations such as adding, subtracting, and so on. The example system could also convert metric values to imperial, and the reverse.

The system would have forms (for example, CalculatorForm and ConvertorForm) to provide the GUI interface, but the arithmetical and conversion functionality would be encapsulated in separate classes Calculator and Convertor, as shown in the following image.

Whilst the forms do have to be tested for the GUI functionality, the unit tests focus more on the underlying arithmetical and conversion calculations carried out by the functionality classes. For example, a unit test could be written to test the following add method in the Calculator class.

add(n : Integer) updating;
begin
    // 'result' is an attribute in the Calculator class
    result := result + n;
end;

Typically there is one unit test class for each functionality class, as shown in the following image.

It is possible, but not usual, to combine the unit test classes, as shown in the following image.

It is also possible, but not usual, to split testing between two unit test classes, as shown in the following image.

Unit test classes are created as subclasses of the JadeTestCase class. The unit test methods of TestCalculator are designed to put the Calculator class through its paces.

A unit test method asserts the truth of a statement such as the existence or non-existence of an object, the equality of two values, and so on. The methods for making these assertions are provided in the JadeTestCase class. A test fails if it does not perform as expected.

An exception can occur when running a test. Under certain circumstances, the exception is expected and a unit test could be written to confirm that it is raised. Expected exceptions are registered using the expectedException method provided by the JadeTestCase class.

When writing a unit test method, you often have to create test data so that the test is performed for a system in a known state. In addition, you may need to remove the test data when the unit test method is finished. Each unit test method could be responsible for creating and removing its own test data, but the test framework enables you to create separate methods to do this.

A method in a unit test class can be tagged with a method option that indicates its purpose and therefore at what stage in a test run it is executed.

Methods with unitTestBeforeAll and unitTestAfterAll method options can be defined only on the base JadeTestCase class, and there can be one instance only of these method options in a schema.

If any number of tests are run from the schema, the unitTestBeforeAll and unitTestAfterAll method options are executed once only.

If multiple unitTestBeforeAll and unitTestAfterAll method options are defined on methods of the JadeTestCase class in a schema, the first instance of the method option is used and a warning is logged, stating that all other instances have been ignored.

If unitTestBeforeAll and unitTestAfterAll method options are defined on methods in subclasses of the JadeTestCase class, they are ignored and a warning is logged, stating they have been ignored.

The following examples show method options available for methods in a JadeTestCase subclass.

The method options available for methods in a unit test class are listed in the following table.

Method Option This method is …
unitTestBeforeAll Run once before any classes are tested. Only one method in the class can have this method option.
unitTestBeforeClass Run once before the class is tested. Only one method in the class can have this method option.
unitTestAfterClass Run once after the class is tested. Only one method in the class can have this method option.
unitTestAfterAll Run once after all classes have been tested. Only one method in the class can have this method option.
unitTestBefore Run before each unit test method of the class is executed. Only one method in a JadeTestCase subclass should have this option.
unitTestAfter Run after each unit test method of the class is executed. Only one method in a JadeTestCase subclass should have this option.
unitTest A unit test method. It cannot have parameters or return a result. The test fails if an assertion method fails or an exception is raised.
unitTestIgnore A unit test method that is ignored when the tests are run. A possible reason for not running the test is that the unit test method is incomplete or the underlying functionality to be tested is incomplete.