@head @module unittest @title unittest: Unit testing framework

This module contains a simple unit testing framework that can be used for implementing automated unit tests for Alore programs.

Introduction

A test case tests a single feature of a program. A suite is a collection of related test cases. Typically test cases are implemented as methods of a test suite class. A test suite class must be a subclass of @ref{Suite}.

The class below is a simple test suite that tests functions in the mymodule module, which we assume to define the function Add and Multiply: @example import unittest import mymodule class MySuite is Suite def testAdd() AssertEqual(Add(1, 1), 2) end def testMultiply() AssertEqual(Multiply(2, 3), 6) end end @end

Only methods whose names start with "test" become test cases of a suite. The @ref{AssertEqual} function can be used to verify that two values are equal.

The @ref{RunTest} function is used to execute a test suite: @example RunTest(MySuite()) @end

The above program executes the two test cases testAdd and testMultiply. Any test cases that raise an uncaught exception due to an assertion failure or any other reason are reported to the programmer.

If we save the program above as test.alo, we can run the test cases like this: @example $ alore test.alo 2 test cases run, all passed. *** OK *** $ @end

Class Suite

@class Suite() @desc Construct a Suite object. All members defined in subclasses that start with test are assumed to represent test cases or child suites. Members that are instances of Suite represent child suites and other members are assumed to represent test cases. @end

Suite methods

@fun addTest(testcase as TestCase) @desc Add a test case to the suite. This method can be used to add manually constructed instances of the @ref{TestCase} class or its subclass as members of a suite. @end @fun setUp() @desc This method is called before executing each test case in the suite. The default implementation does nothing. Override this to setup member variables, files and other common state needed by test cases. @end @fun tearDown() @desc This method is usually called after executing each test case in the suite, even if the test case failed. The default implementation does nothing. Override this to clean up the results of the setUp method or test cases. @end @fun skip() @desc Skip the current test case. The number of skipped test cases is reported by @ref{RunTest}, and if the "-v" flag is present, they are also marked in the list of executed test cases as skipped. @end

Class TestCase

@class TestCase(name as Str[, suite as Suite[, function as def ()]]) @desc Construct a test case object. The optional suite argument defines the test suite that contains this test case. The optional function argument, a callable object that accepts no arguments, will be called when the case is run. @end

TestCase methods

@fun setUp() @desc If suite is defined, calls the setUp method of the suite. setUp is called before running the test case. @end @fun tearDown() @desc If suite is defined, calls the tearDown method of the suite. tearDown is called after running the test case even if the test case failed. @end @fun run() @desc Run the test case. By default, calls the function given to the constructor or does nothing if the function was not provided. This method should raise an exception on test case failure. @end @end-class

Functions

@fun RunTest(test as Suite[, args as Array]) @desc Run a test case or a test suite. The optional args parameter may be a sequence of strings that represent the command line arguments to the tester. Status information is displayed on the StdOut stream.

The args array optionally starts with a "-v" flag. If present, it causes the function to display the names of all test cases as they are being run. Finally, the args array may contain a test case filter pattern. The pattern may contain asterisks (*) as wild card characters. It is used to specify the names of test cases to run.

Member test... of a test suite is named test.., unless the test suite is a child suite, in which case the name is prefixed with the name of the parent test suite and a dot (.).

For example, if args is ["testChild.*"], only the test cases in the testChild child suite are run. @end @fun Fail() @desc Fail a test case by raising @ref{AssertionFailure}. @end @fun Assert(bool as Boolean[, message as Str]) @desc Raise @ref{AssertionFailure} if bool is not True. If the message is provided, it is associated with the exception. @end @fun AssertEqual(a, b) @desc Raise @ref{AssertionFailure} if a != b. @end @fun AssertNotEqual(a, b) @desc Raise @ref{AssertionFailure} if a == b. @end @fun AssertRaises(exception as Type[, message], function, arguments = []) @desc Call the function with the given arguments. Raise @ref{AssertionFailure} if the function does not raise an exception of the type specified by exception. Additionally, if the message argument is given, verify that the message member of the exception is equal to the message argument. Example: @example AssertRaises(TypeError, Ord, [5]) -- Verify that Ord does not accept -- an integer argument. @end @end @fun AssertType(type as Type, x) @desc Raise @ref{AssertionFailure} if x is not an instance of the specified type. @note Instances of subclasses of the type are not accepted. @end @end

Exceptions

@class AssertionFailure([message as Str]) @desc This exception is raised when an assertion is failed in a test case. This class is derived from @ref{std::Exception}. @end @end-class