I want to write unit tests in SWI-Prolog (version 7.6.4) in order to streamline and automate testing, which is currently done only in a manual, ad-hoc fashion.
The files to be tested contain complex algorithms that make use of predicates from modules, which in turn operate on user-defined predicates (that serve as input data or problem instance). As a minimal example, consider the following:
File 'graph.pl' (input data and algorithm):
:- use_module(path).
edge(a,b).
edge(b,c).
edge(c,d).
reachable(X,Y) :-
path(X,Y), !.
reachable(X,Y) :-
path(Y,X), !.
File 'path.pl' (the module):
:- module(path, [path/2]).
path(X,X).
path(X,Y) :-
user:edge(X,Z),
path(Z,Y).
Queries run as expected:
?- [graph].
true.
?- reachable(a,a).
true.
?- reachable(a,d).
true.
?- reachable(d,a).
true.
Let us include these queries into a test file 'graph.plt':
:- begin_tests(graph).
:- include(graph).
test(1) :-
reachable(a,a).
test(2) :-
reachable(a,d).
test(3) :-
reachable(d,a).
:- end_tests(graph).
When I then run the tests, I get:
?- ['graph.plt'].
true.
?- run_tests.
% PL-Unit: graph .
ERROR: /home/jens/temp/graph.plt:6:
test 2: received error: path:path/2: Undefined procedure: edge/2
ERROR: /home/jens/temp/graph.plt:8:
test 3: received error: path:path/2: Undefined procedure: edge/2
done
% 2 tests failed
% 1 tests passed
false.
That is to say, when called from within the test suite, the module is no longer able to 'see' the predicate 'edge' under the 'user:' namespace. Is this a bug, or am I missing something?