Search code examples
unit-testingprologgnu-prolog

Unit testing in GNU Prolog


I'm trying to migrate my SWI Prolog application into the GNU Prolog. Unfortunately I have a problem with unit tests. In SWIPL we can simply use plunit module and write the test cases like the following one:

:- begin_tests(my_tests).
test(my_predicate_test) :- my_predicate(Result), assertion(Result == [foo, bar]).
test(second_test) :- foo(10, X), assertion(X == "hello world").
:- end_tests(my_tests).

But how to implement unit tests in GNU Prolog? Even some additional libraries like crisp are not available for gprolog.


Solution

  • You can use lgtunit. Its main features are summarized here. Most of your tests could be run as-is or easily converted. Using your example:

    :- object(tests, extends(lgtunit)).
    
        :- uses(lgtunit, [assertion/1]).
        :- uses(user, [my_predicate/1, foo/2]).
    
        test(my_predicate_test) :-
            my_predicate(Result),
            assertion(Result == [foo, bar]).
    
        test(second_test) :-
            foo(10, X),
            assertion(X == "hello world").
    
    :- end_object.
    

    The tool supports multiple test dialects, some of them common to plunit. E.g.

    :- object(tests, extends(lgtunit)).
    
        :- uses(user, [my_predicate/1, foo/2]).
    
        test(my_predicate_test, true(Result == [foo, bar]) :-
            my_predicate(Result).
    
        test(second_test, true(X == "hello world")) :-
            foo(10, X).
    
    :- end_object.
    

    Assuming that you're testing plain Prolog code (given that you're using GNU Prolog), Logtalk's Prolog standards compliance suite provides plenty of examples.

    You can also export test results in multiple industry standards such as TAP and xUnit and generate reports for easy browsing (see e.g. https://infradig.github.io/trealla/).

    For further advise on testing, see also these blog posts.