LoginSignup
7
7

More than 5 years have passed since last update.

SWI-Prolog でもテストを書こうの話

Last updated at Posted at 2017-12-04

はじめに

Prlog でもテスト書けるといいよなと思ったりするわけです。
SWI-Prologでもテスト書けるのでしょうか?
答えはYesです。ということでご報告する次第であります。

1. とりあえず使ってみる

例えば以下のようなPrologの述語定義があります。

% fun1.pl
add(A,B,C) :- C is A+B.
mul(A,B,C) :- C is A*B.

これをテストするには以下のように書きます:

% funtest1.pl
:- use_module(fun).

:- begin_tests(add).
  test(add1_2) :- add(1,2,3).
  test(add0_1) :- add(0,1,1).
:- end_tests(add).

:- begin_tests(mul).
  test(mul1_2) :- mul(1,2,2).
  test(mul0_1) :- mul(0,1,0).
  test(mul10_20) :- mul(10,20,200).
:- end_tests(mul).

:- run_tests.
:- halt.

テストコードは begin_tests/1end_tests/1 で、はさんで書きます。このとき、 :- を忘れずに書きましょう。これ書いてて最初動かず悩んでしまいましたw

実行するにはrun_testsを実行すれば動きます。
begin_testsend_tests の名前は同じでないといけません。
かなり綺麗にテストを書くことが出来ます。

テスト実行は

$ swipl funtest.pl
% PL-Unit: add .. done
% PL-Unit: mul ... done
% All 5 tests passed

簡単すぎる?

2. モジュールを切り替えて使う。

では実際にもう少し複雑な使い方をしてみましょう。
先程の、プログラムをfun.plという名前で保存しています。

:- module(fun, [add/3,mul/3]).
% fun.pl
add(A,B,C) :- C is A+B.
mul(A,B,C) :- C is A*B.

ところで、別なバージョンの実装をつくることにしたとしましょう。

:- module(fun2, [add/3,mul/3]).
% fun2.pl
add(A,B,C) :- C is A+B.
mul(A,B,C) :- C is A*B.

面倒くさいので同じプログラムをコピっただけですが、同じテストプログラムでテスト出来たら便利です。

そんなときは、コマンドライン引数を見て読み込むモジュールをかえられるようにしています。

% funtest.pl
:- current_prolog_flag(argv, [M]),!,format('use ~w\n',[M]),use_module(M) ;
   use_module(fun).

:- begin_tests(add).
  test(add1_2) :- add(1,2,3).
  test(add0_1) :- add(0,1,1).
:- end_tests(add).

:- begin_tests(mul).
  test(mul1_2) :- mul(1,2,2).
  test(mul0_1) :- mul(0,1,0).
  test(mul10_20) :- mul(10,20,200).
:- end_tests(mul).

:- run_tests.
:- halt.

こうしておくとデフォルトではfun.plのテストがされ

$ swipl funtest.pl
% PL-Unit: add .. done
% PL-Unit: mul ... done
% All 5 tests passed

fun2.plのてすとをしたいときは以下のように引数を渡すことでテストできます。

$ swipl funtest.pl fun2
use fun2
% PL-Unit: add .. done
% PL-Unit: mul ... done
% All 5 tests passed

3. Makefile を書こう。

Makefileを作って

test: test1 test2
test1:
    swipl funtest.pl
test2:
    swipl funtest.pl fun2

などと書いておくと、

$ make test
swipl funtest.pl
% PL-Unit: add .. done
% PL-Unit: mul ... done
% All 5 tests passed
swipl funtest.pl fun2
use fun2
% PL-Unit: add .. done
% PL-Unit: mul ... done
% All 5 tests passed

でまとめてテスト出来て便利です。

3. 更に詳しい情報

SWI-Prologの Prolog Unit Tests にはさらに詳しい情報が掲載されています。参考にしてください。

4. まとめ

SWI-Prologでテストを書いてみました。
この記事のプログラムは以下からダウンロードできます:

:octocat: https://gist.github.com/hsk/ff712ab7e4ba400211557a3e59ed381f

参考

Prolog Unit Tests

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7