OUnitでユニットテスト
これまで、ちょこちょこOCamlを触ってみて感じたことなのですが、OCamlはコンパイル時の型チェックが非常に強力なので、
- コンパイルが通るまでが一苦労
- でも、起動させると期待通り動く
ということが他の言語に比べると多いように思います(コンパイルエラーが取れにくいのは私のショボさではありますが…)。
とはいえ、当然ユニットテストはおろそかにできませんし、何よりこの一年ですっかりtest first厨になってしまった私は「先にテスト書きたい」という欲求を抑えられません。
ちょっと探してみたところ、OUnitというユニットテスト用のパッケージがあるようなので、それを試してみたいと思います。環境は前回同様FreeBSD6.3で、devel/ocaml-ounitというports経由でOUnitをインストールしています。
今回は例として二分木をやってみます。
新人のときのCの練習以来の二分木です。ドキドキします。テストスクリプト(test_tree.ml)はこんな感じ。
open OUnit
open Tree
let setup _ =
Br(6, Br(3, Br(1, Lf, Lf), Br(2, Lf, Lf)),
Br(5, Lf, Br(4, Lf, Lf)))
let teardown _ = ()
let test_list_of_tree_pre t =
let l = list_of_tree_pre t in
assert_equal l [6; 3; 1; 2; 5; 4]
let test_list_of_tree_in t =
let l = list_of_tree_in t in
assert_equal l [1; 3; 2; 6; 5; 4]
let test_list_of_tree_post t =
let l = list_of_tree_post t in
assert_equal l [1; 2; 3; 4; 5; 6]
let suite = "Test Tree" >:::
["test_list_of_tree_pre" >::
(bracket setup test_list_of_tree_pre teardown);
"test_list_of_tree_in" >::
(bracket setup test_list_of_tree_in teardown);
"test_list_of_tree_post" >::
(bracket setup test_list_of_tree_post teardown)]
let _ = run_test_tt_main suite
Treeモジュール内で type 'a tree = Lf | Br of 'a * 'a * 'a tree が定義され、行きがけ順、通りがけ順、帰りがけ順でリストを作成する関数が定義されるつもりで、それらの関数をテストします。そして、以下がサンプル二分木のイメージ図です。
6
+--+--+
| |
3 5
+-+-+ +-+
| | |
1 2 4
ちなみに、OUnitモジュールのbracketという関数はテストのセットアップと後始末をやってくれています。
そしておもむろに
$ ocamlbuild -ocamlc 'ocamlfind c -package oUnit -linkpkg' test_tree.byte
と叩いてみます。Tree(tree.ml)モジュールが無いので当然コンパイルエラーになります。
なお、ここで使っているocamlbuildはOCaml3.10から標準配備されたビルドツールだそうです。すごい便利なんですが、パッケージ管理ツールであるocamlfindとの連携がすっきりしない…
$ ocamlbuild -pkg oUnit test_tree.tyte
とか、できると素敵なんですけども。
と、それはさておき。今度はテストに通るべくtree.mlのコーディングを頑張ります。
四苦八苦は省略して、えいっ!
type 'a tree = Lf | Br of 'a * 'a tree * 'a tree
let list_of_tree_pre tree =
let rec loop t l =
match t with
| Lf -> l
| Br (v, left, right) -> v :: loop left (loop right l) in
loop tree []
let list_of_tree_in tree =
let rec loop t l =
match t with
| Lf -> l
| Br (v, left, right) -> loop left (v :: loop right l) in
loop tree []
let list_of_tree_post tree =
let rec loop t l =
match t with
| Lf -> l
| Br (v, left, right) -> loop right (loop left l) @ [v] in
loop tree []
そして、先程のocamlbuildコマンドを叩いて生成されたtest_tree.byteを叩くと
./test_tree.byte
...
Ran: 3 tests in: 0.00 seconds.
OK
やったぁ。
OCamlの場合、コンパイルが通るだけでも達成感があるのですが、その後すぐOUnitも通りやすいので、ダブルの達成感が得られます。達成感マニアにはたまらないかと思います。
あと、まじめな話、CやPerl、Rubyのように「意図せず、NULLやundefやnilが渡ってきちゃってエラー」という失敗が無い(と言いきっちゃってよいのかしら?)ので、その辺り個人的には凄く嬉しいです。ぬるぽも言わずもがな。
まだまだ、使っているというより触っている程度なので、良く分かっていないところが結構多いんですが(特にファンクターはスルー)、もうしばらく弄ってみたいと思います。
- 前のエントリー: OCamlで簡易SSLクライアント
- 2人の推薦記事
- 0人がクリップ
-
ソーシャルブックマーク(-)
- トラックバック(0)
- 今日のトップ記事
- 2日前
- 3日前
- 4日前
- 6日前
- 7日前
- ホワイトペーパー
-
VERITAS Storage Foundation
-
ENSEMBLEによるリアルタイム・エンタープライズ・ビジネス・アクティビティ・モニタリングの実現
-
ブランク・パネルを使ってラックの冷却効率パフォーマンスを改善する
-
【Symantec Mail Security 8200 Series】
信頼のアンチウイルス、業界をリードするアンチスパムなど、数々のセキュリティ機能を統合して電子メールのセキュリティを包括的に確保
-
エンタープライズJavaの仮想化とアプリの総所有コスト(TCO)の関係を知る
-
短期間で実現する、経営ダッシュボードシステム! 「MyB3Smart」
-
【導入事例】「XMLデータベース」がもたらす3つのメリットとは?
-
【サイト内検索機能をASPでご提供】月額9450円!SEO/SEMの次はこれ!1ヶ月間無料お試し版付き。
-
分散化の進むオフィス環境においてファイル管理を効率化する方法 〜ファイル管理と移行のための最適なアプローチとは?
-
増え続けるファイルデータ。高まるデータ保護と事業継続への要求。データ可用性とデータ保護に優れ、かつコスト効率の高い分散型エンタープライズ環境を実現するためのヒントとは?
〜Brocade StorageXレプリケーション機能が可能にするリソース利用率の最適化とデータ保護
- 話題のタグ
Firefox 3が対応したdisplayプロパティの値(3) - inline-table
MSもアドビも学生さんに開発ソフトを無償提供
「Economist」のトップページがリニューアル
あなたがプログラムを理解できない10の理由:第2回
新APIまもなく登場--Google Developer Day 2008の見所とは?
仮想化によるコスト削減を見える化:オンラインTCOカリキュレータ
リスティング広告における競争優位性の維持
-Simplify IT- ITをシンプルに 連載第2回
内部統制対策を実現するIT運用管理ツール