QuickCheck メモ

QuickCheck はテストケースを自動で作成してくれる、というのを知った。http://d.hatena.ne.jp/kazu-yamamoto/20101027/1288173335。少し試してみた。

install

Ubuntu 10.04.1

% sudo apt-get install libghc6-quickcheck2-dev
sample code
import Test.QuickCheck
-- 標準の lookup 関数と同様の関数
search :: Eq k => k -> [(k,v)] -> Maybe v
search _ [] = Nothing
search k ((key, value) : xs) | k == key  = Just value
                             | otherwise = search k xs

prop_model0 :: String -> [(String, Int)] -> Bool
prop_model0 k xs = search k xs == lookup k xs
run test
GHCi> quickCheck prop_model0
+++ OK, passed 100 tests.

search という関数は、Prelude で定義されている lookup と同じ機能の関数なので、prop_model0 の定義は簡潔になっている。ただ、実践的なモノを作る場合、すでに定義されている関数と同様の関数を作ることはまずない。そういった場合のテストケースの定義はどうすればよいのだろう。その定義が正しいかどうかは、どうやって保証するのだろう。

わざと間違えてみる
search :: Eq k => k -> [(k,v)] -> Maybe v
search _ [] = Nothing
search k ((key, value) : xs) | k == key  = Just value
                             | otherwise = Nothing    -- ここを変更
run test
GHCi> quickCheck prop_model0
*** Failed! Falsifiable (after 59 tests and 8 shrinks):    
""
[("a",0),("",0)]

テストで使用されるパターンは毎回別のパターンになるらしく、少ない確率だけれどテストをパスすることがある。