Logtalk provides simple but portable support for writing unit tests. This support is provided by a library object,
lgtunit, inspired on the works of Joachim Schimpf (ECLiPSe library
test_util) and Jan Wielemaker (SWI-Prolog
plunit package). You can load it using the goal:
| ?- logtalk_load(library(lgtunit)).
The interface of the
lgtunit object is quite simple and can be found e.g here:
Most of the examples found on the current Logtalk distribution include a set of unit tests, together with a handy loader file named
tester.lgt. Typically, this loader file loads the code you want to test, the unit test framework, the unit tests themselves, and send a
run/0 message to the unit test objects. Check, for instance, the example:
In order for you to write your own unit tests, start by defining objects extending the
lgtunit object. These objects must be compiled using the option
hook(lgtunit). For example:
| ?- logtalk_load(my_tests, [hook(lgtunit)]).
After successful compilation and loading of your unit test objects, you can run them by typing:
| ?- my_tests::run.
Logtalk unit tests can be written using any of three different dialects. The most simple dialect is:
test(Test) :- Goal.
This dialect allows the specification of tests that are expected to succeed. Tests that are expected to fail can be written by using the
\+/1 built-in predicate. However, tests that are expected to throw an error cannot be specified. A second dialect overcomes this restriction:
succeeds(Test) :- Goal. fails(Test) :- Goal. throws(Test, Error) :- Goal.
This is a straightforward dialect. For
Goal is expected to succeed. For
Goal is expected to fail. For
Goal is expected to throw
Error. A third supported dialect is:
test(Test, Outcome) :- Goal.
In this case,
Outcome can be the atom
true, the atom
fail, or the exception term that the test is expected to throw. In all cases,
Test is an atom, uniquely identifying a test. Simply use the dialect that is the best fit for your application.
That’s all. Happy testing!
Note: when using the
<</2 control construct to access and test an object internal predicates, make sure that the objects are compiled with the
context_switching_calls flag set to