作为这个问题的一个例子,我有一个非常简单的Prolog文件 main.pl
,其中我定义了一些形状的颜色 .
colour(circle, red).
colour(triangle, red).
colour(square, blue).
现在,我定义了一个谓词 same_colour/2
,如果 S1
和 S2
是相同的颜色,则为真 .
same_colour(S1, S2) :-
colour(S1, C),
colour(S2, C).
顶级测试表明此谓词按预期工作 .
?- same_colour(circle, triangle).
true.
?- same_colour(circle, square).
false.
我正在尝试使用SWI-Prologs单元测试框架plunit为 same_colour/2
编写单元测试,但我想在每个单独的测试中声明只在该测试范围内的事实 . 我已尝试将 setup
选项用于单个测试,以及 asserta
,两者都不起作用 . 以下所有测试都失败了 .
:- begin_tests(same_colour).
test(same_colour) :-
colour(shape_a, colour_1),
colour(shape_b, colour_1),
same_colour(shape_a, shape_b).
test(same_colour) :-
asserta(colour(shape_a, colour_1)),
asserta(colour(shape_b, colour_1)),
same_colour(shape_a, shape_b).
test(same_colour, [
setup(colour(shape_a, colour_1)),
setup(colour(shape_b, colour_1))
]) :-
same_colour(shape_a, shape_b).
:- end_tests(same_colour).
我也尝试过:
test(same_colour, [
setup(asserta(colour(shape_a, colour_1))),
setup(asserta(colour(shape_b, colour_1))),
cleanup(retract(colour(shape_a, colour_1))),
cleanup(retract(colour(shape_b, colour_1)))
]) :-
same_colour(shape_a, shape_b).
也就是说,首先声明 colour(shape_a, colour_1)
和 colour(shape_b, colour_1)
是事实,进行测试,然后'undeclare' . 但是,此测试也失败了 . 使用 trace
似乎 colour(shape_a, colour_1)
永远不会被断言(或者在我的测试运行时至少不是真的 . )
Call: (18) plunit_same_colour:'unit body'('same_colour@line 13', vars) ? creep
Call: (19) same_colour(shape_a, shape_b) ? creep
Call: (20) colour(shape_a, _G738) ? creep
Fail: (20) colour(shape_a, _G738) ? creep
Fail: (19) same_colour(shape_a, shape_b) ? creep
Fail: (18) plunit_same_colour:'unit body'('same_colour@line 13', vars) ? creep
我现在可以理解为什么前两个测试不起作用 . 在第一个我正在测试 colour(shape_a, colour_1)
是否为真,当它没有't been declared before, and in the second I just don'认为在谓词定义中使用 asserta
是正确的 . 虽然感觉类似于我的第三或第四次测试应该能够实现我想做的事情?
2 回答
测试你的测试:)
产量
也就是说,如果你想在运行时修改数据库,请让Prolog知道,添加:
现在它变得更好了:
但数据库是“脏”的:
当然,它是一项危险的活动......无论如何,设置/清理是目标,所以也许你想要
您可以在替代Logtalk的单元测试框架中使用简单的解决方案:
https://github.com/LogtalkDotOrg/logtalk3/blob/master/tools/lgtunit/NOTES.md
SWi-Prolog是十二种支持的Prolog系统之一 . 无需使用
dynamic/1
指令或清理目标 .例如,假设您要使用三组事实来测试代码 . 此外,假设要测试的代码在
same_color.pl
Prolog文件中定义 . 只需为每组事实定义一个单元测试对象:定义对象,例如
colors2
和colors3
用于其他事实 . 然后:或者只需通过定义
tester.lgt
帮助文件并运行logtalk_tester
自动化shell脚本来自动化单元测试 . 大量示例,包括Logtalk发行版中的示例tester-sample.lgt
文件 . 如果您发现使用Logtalk单元测试工具测试Prolog代码很奇怪,请知道Logtalk发行版包含完整的Prolog标准一致性测试套件,它为您提供了更多示例 .