Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away