2011年12月23日金曜日

Test.Framework & TemplateHaskell

LeftistHeapの実装をQuickCheckでテストするコードを有識者に見てもらったところ、QuickCheck単体で使うのではなく、TestFramework (とそのTemplateHaskell版) を使うのがいまどきのコードだと聞いたのでやってみた。

{-# LANGUAGE TemplateHaskell #-}
module TestLeftistHeap where

import Test.Framework.TH
import Test.Framework
import Test.HUnit
import Test.Framework.Providers.HUnit
import Test.Framework.Providers.QuickCheck2

import Data.List
import LeftistHeap

main = $(defaultMainGenerator)

prop_insert :: [Int] -> Bool
prop_insert ns = test' lh $ sort ns
  where
    lh :: LeftistHeap Int
    lh = foldl (\h n -> LeftistHeap.insert n h) empty ns
    
    test' :: (LeftistHeap Int) -> [Int] -> Bool
    test' _ []     = True
    test' h (m:ms) = findMin h == m && test' (deleteMin h) ms

TestFrameworkは、QuickCheckによるプロパティテストと、HUnitによるunit testとをひとつにまとめて並列に実行してくれる(ただし、テスト結果のdiffを取りやすいように、結果は決まった順序で出力する)フレームワークだそうです。と、Hackageのページを直訳してみる。

TemplateHaskellは、Haskell版プリプロセッサ(多分)。使わないコードを "{- ... -}" で囲んでコメントアウトしておいても、なんかパースされてコンパイルエラーになってしまった。一般的な使い方はよくわからないが、TestFrameworkと共に使うと、ほんの少しだけコード量が少なくなる。