24694


OCamlでコードを書くさいに、ユニットテストを書きたいため、[OUnit](http://ounit.forge.ocamlcore.org/)を利用しています。

そのとき、`foobar.ml`と`foobar_test.ml`といったように、ファイルを分けているのですが、[ドキュメントを見る限り](http://ounit.forge.ocamlcore.org/api-
ounit/index.html)ですとユニットテストを実行する方法として:

[code]

    ocamlfind ocamlc -o test -package oUnit -linkpkg -g foobar.ml foobar_test.ml
    
[/code]

というのが紹介されているのですが、毎回これを実行するのは、コマンドとして長い印象があります。仕方無いので、`make.sh`みたいな、シェルスクリプトとして、上記のラインを書いて、そこから実行しています。ですが、これはバッドノウハウのように思えて、あまりすっきりとしません。

OCamlを書くさいに、OUnitを実行するときの、良い方法があれば、教えていただけないでしょうか。


CC BY-SA 3.0
2016-05-09T22:44:41.543
24683
2016-11-06T15:48:50.707
2016-11-06T15:48:50.707
754
939
question
ocaml
OUnitをできるだけ簡単に実行するための方法


# ocamlbuildを使う

この場合であれば、ワーキングディレクトリにて、`_tags`を作成して以下のように書き込みます。

[code]

    true: debug, linkpkg, thread
    true: package(oUnit)
    
[/code]

そして以下のコマンドでビルドできます。

[code]

    ocamlbuild -use-ocamlfind "foobar.native" "foobar_test.native"
    
[/code]

`<mlファイル名>.native`でocamloptによるバイナリへのビルド、  
`<mlファイル名>.byte`でocamlcによるバイトコードへのビルドになります。

`_tags`について簡単に触れておくと、カンマ区切りの左側が「後続のオプションを付ける条件」の記述で、常に適用したいオプションを`true`にします。ファイル名やディレクトリに応じたオプションの指定はここに記述します。右側にはオプションを設定します。両者の一覧は後述のマニュアルを参照して下さい。

ocamlbuildの詳細なマニュアルは[こちら](https://github.com/ocaml/ocamlbuild/blob/master/manual/manual.adoc)になります。_tagsでppxやsyntax
extension、果ては最新のocamlで追加されたflambdaによる最適化も行う説明も載っています。

正直これでも冗長だと思っていますが、公式に取り込まれたドキュメント(先程のマニュアル)によれば将来-use-
ocamlfindはデフォルトになるかもしれないものの、シェルのエイリアス等で対処しておくことをおすすめしているようです。

# ここからは余談

### mliの自動生成

上記の設定でpackageを配置した上で、

[code]

    ocamlbuild -use-ocamlfind "foobar.inferred.mli"
    
[/code]

とすると`foobar.ml`のシグネチャを推論したmliが自動生成されます。勿論人間の手直しも必要ですが、mliを良いドキュメントとする土台として非常に便利なので憶えておいて損は無いと思われます。

### プロジェクトの管理

また、ocamlbuildは簡単な設定ならば便利なのですが、これだけでプロジェクトを管理するのは大変です。ocamlbuildを細かく操作できるらしい`myocamlbuild.ml`は私も手書きしてません…  
もし今まとまった物を作っていらっしゃるのであれば、OASISをおすすめしておきます。  
(ユニットテストという単語からそんな雰囲気がしたので)  
Lwtを始めとした多くのプロジェクトで[実用されており](https://github.com/ocsigen/lwt/blob/master/_oasis)、見覚えのある感じの管理ができます。  
[使い方はこちら](https://ocaml.org/learn/tutorials/setting_up_with_oasis.html)です。


CC BY-SA 3.0
2016-05-10T02:49:53.143
24693
2016-05-28T12:40:58.667
2016-05-28T12:40:58.667
7179
7179
24683
answer


ユニットテストが必要なレベルのプログラムを書くのならばビルドツールを使ってください。`make` でも `ocamlbuild` でも `omake`
でもなんでもいいです。

私はテストとライブラリを別けるのは面倒なので全部一つにまとめています。つまり、 `foobar.ml` の中に `foobar_test.ml`
の内容を書きます。テストが常にリンクされてしまうのが難点ですが、実行ファイルサイズに極端に制限のある埋め込み環境でもない限りハードディスクは安いですし気にすることは無いと思います。この場合、常にテストが走ってしまうのでは意味が無いので、

[code]

    let () = Arg.parse ["--test", Arg.Unit (fun () -> OUnit2.run_test_tt_main test), "run embed tests"] (fun _ -> ...) "myapp <options>"
    
[/code]

のようにして `--test` オプションをつけた場合にのみテストが走るようにしています。


CC BY-SA 3.0
2016-05-10T02:50:54.090
24694
2016-05-10T02:50:54.090
898
24683
answer