SML/NJでのUnitTest環境の構築

SMLのUnit Testライブラリを見つけました.
このsml-extライブラリにはいくつかの種類のモジュールが含まれており, その内の一つにUnitTestsというstructureが用意されています.
SML/njから使う方法を書きます.

インストール

  • チェックアウト
 svn checkout http://sml-ext.googlecode.com/svn/trunk/ sml-ext-read-only
  • vi sml-ext

そのままコンパイルするとエラーが出るため修正します(使ったリビジョンは648(現時点でtrunkのhead)です)

 signature SmlExt'ORD_SET_EXT
 ↓
 signature SmlExt'SmlNjLib'ORD_SET_EXT
$ cd sml-ext-read-only/
$ echo 'CM.stabilize true "sml-ext.cm";' | sml
$ echo "sml-ext.cm sml-ext.cm" >> $SMLNJ_HOME/lib/pathconfig
  • ファイルを移動
$ mv sml-ext-read-only $SMLNJ_HOME/lib/sml-ext.cm
  • おめでとう!

使ってみる

$ cat test.cm
Library
  structure SmlExt
  structure Test
is
  $/basis.cm
  $/sml-ext.cm
  test.sml
  • テストを記述する.
$ cat test.sml
structure Test =
struct
  open SmlExt.UnitTests
  open Ops
  fun test () =
    $ ("Test" (* 全体に名前付ける *)
    , &[ % (fn()=> assertEqualEq (0, 0)) (* 0==0 *)
       , % (fn()=> assertEqualEq (0, 1)) (* 0==1 *)
       , % (fn()=> assertEqualEq (0, 2)) 
       , % (fn()=> assertEqualInt (1, 0))
	   (* ケースに名前を付ける *)
       , $ ("1==1", % (fn()=> assertEqualInt (1, 1)))
       , % (fn()=> assertEqualInt (1, 2))
       , % (fn()=> assertEqualReal (2.0, 0.0))
	   (* 特殊化された比較アサート *)
       , % (fn()=> assertEqualReal (2.1, 2.1))
       , % (fn()=> assertEqualReal (2.2, 2.19999))
       , % (fn()=> assertEqualReal (3.14, 3.14159))
       , % (fn()=> ? (6 = foldr op+ 0 [1,2,3]))
       , $ ("sum[1..10]=55",     (* ちょっと実際的?なケース *)
            % (fn()=> ? (55 = foldr op+ 0
                            (List.tabulate(10,fn i=> i)))))
      ])
end

すこし記述が鬱陶しいですが,しょうがないトコですね.

  • 実行する
$ sml
- CM.make "test.cm";
- SmlExt.UnitTests.runTest(Test.test());
### Failure in: Test:1
Failure : expected :<<no printer>>
          actual   :<<no printer>>
### Failure in: Test:2
Failure : expected :<<no printer>>
          actual   :<<no printer>>
### Failure in: Test:3
Failure : expected :<1>
          actual   :<0>
### Failure in: Test:5
Failure : expected :<1>
          actual   :<2>
### Failure in: Test:6
Failure : expected :<2.0>
          actual   :<0.0>
### Failure in: Test:8
Failure : expected :<2.2>
          actual   :<2.19999>
### Failure in: Test:9
Failure : expected :<3.14>
          actual   :<3.14159>
### Failure in: Test:11:sum[1..10]=55 (* 上で付けた名前が表示されている *)
Failure :

Cases    : 12
Tried    : 12
Failures : 8
Errors   : 0
Time     : 0.000

val it = () : unit

テスト出来ました〜 (^^)v


これでインタプリタで動く単体テスト環境が出来ました.