SWI-Prolog 中的单元测试:模块内用户谓词的可见性
Unit Tests in SWI-Prolog: Visibility of User Predicates from within a Module
我想编写 unit tests in SWI-Prolog(版本 7.6.4)以简化和自动化测试,目前仅以手动、临时方式完成。
要测试的文件包含复杂的算法,这些算法使用模块中的谓词,这些模块又对用户定义的谓词(用作输入数据或问题实例)进行操作。作为一个最小的例子,请考虑以下内容:
文件'graph.pl'(输入数据和算法):
:- use_module(path).
edge(a,b).
edge(b,c).
edge(c,d).
reachable(X,Y) :-
path(X,Y), !.
reachable(X,Y) :-
path(Y,X), !.
文件'path.pl'(模块):
:- module(path, [path/2]).
path(X,X).
path(X,Y) :-
user:edge(X,Z),
path(Z,Y).
按预期查询 运行:
?- [graph].
true.
?- reachable(a,a).
true.
?- reachable(a,d).
true.
?- reachable(d,a).
true.
让我们将这些查询包含到测试文件中 '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).
然后 运行 测试时,我得到:
?- ['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.
也就是说,当从测试套件中调用时,模块不再能够 'see' 'user:' 命名空间下的谓词 'edge'。这是一个错误,还是我遗漏了什么?
我自己找到了答案。事实证明,这里没有任何问题,但这个问题只是 RTFM 的另一种情况。来自 PlUnit documentation:
3 Using separate test files
Test-units can be embedded in normal Prolog source-files.
Alternatively, tests for a source-file can be placed in another file
alongside the file to be tested. Test files use the extension .plt.
The predicate load_test_files/1 can load all files that are related to
source-files loaded into the current project.
因此,如果使用单独的 .plt
文件进行测试,您应该先加载原始源文件,然后调用 load_test_files/1
(可能使用 make
或 make(all)
如 options), 然后 run_tests
:
?- [graph].
true.
?- load_test_files([]).
true.
?- run_tests.
% PL-Unit: graph ... done
% All 3 tests passed
true.
我想编写 unit tests in SWI-Prolog(版本 7.6.4)以简化和自动化测试,目前仅以手动、临时方式完成。
要测试的文件包含复杂的算法,这些算法使用模块中的谓词,这些模块又对用户定义的谓词(用作输入数据或问题实例)进行操作。作为一个最小的例子,请考虑以下内容:
文件'graph.pl'(输入数据和算法):
:- use_module(path).
edge(a,b).
edge(b,c).
edge(c,d).
reachable(X,Y) :-
path(X,Y), !.
reachable(X,Y) :-
path(Y,X), !.
文件'path.pl'(模块):
:- module(path, [path/2]).
path(X,X).
path(X,Y) :-
user:edge(X,Z),
path(Z,Y).
按预期查询 运行:
?- [graph].
true.
?- reachable(a,a).
true.
?- reachable(a,d).
true.
?- reachable(d,a).
true.
让我们将这些查询包含到测试文件中 '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).
然后 运行 测试时,我得到:
?- ['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.
也就是说,当从测试套件中调用时,模块不再能够 'see' 'user:' 命名空间下的谓词 'edge'。这是一个错误,还是我遗漏了什么?
我自己找到了答案。事实证明,这里没有任何问题,但这个问题只是 RTFM 的另一种情况。来自 PlUnit documentation:
3 Using separate test files
Test-units can be embedded in normal Prolog source-files. Alternatively, tests for a source-file can be placed in another file alongside the file to be tested. Test files use the extension .plt. The predicate load_test_files/1 can load all files that are related to source-files loaded into the current project.
因此,如果使用单独的 .plt
文件进行测试,您应该先加载原始源文件,然后调用 load_test_files/1
(可能使用 make
或 make(all)
如 options), 然后 run_tests
:
?- [graph].
true.
?- load_test_files([]).
true.
?- run_tests.
% PL-Unit: graph ... done
% All 3 tests passed
true.