QuickCheckを試す
30分プログラム、その94。QuickCheckを試す。
同じく、仕様に基づいたテストを行なうらしいRSpecの参考になるかな、と思って。
いいよ、これ。テストデータが自動で作られるのは、新鮮。
使い方
例えば、lengthが満しているべき性質を関数で記述する。
pLengthApp:: [Int]->[Int]->Bool pLengthApp xs ys = myLength (xs++ys) == (myLength xs) + (myLength ys)
そして、これをquickCheckに渡す。
*Main > quickCheck pLengthApp OK, passed 100 tests.
xsやysを自動で生成してくれるのがポイント。
あとは、論文に書いてあった特徴を列挙しておく。
- テストデータの生成はカスタマイズできる
- カスタマイズできるので、ユーザ定義型も生成できる
- 関数も自動生成するよ
- 生成するデータに条件もつけれる。ソートずみのリストとか
- 生成するデータの分布をかえられるよ。
ソースコード
import Test.QuickCheck --- length -- myLength [] = 0 -- myLength (x:xs) = 1 + (myLength xs) myLength xs = foldl (\x _-> x + 1) 0 xs pLengthUnit:: [Int]->Bool pLengthUnit x = myLength [x] == 1 pLengthApp:: [Int]->[Int]->Bool pLengthApp xs ys = myLength (xs++ys) == (myLength xs) + (myLength ys) -- reverse --myReverse [] = [] --myReverse (x:xs) = (reverse xs) ++ [x] myReverse xs = foldl (flip (:)) [] xs pReverseUnit :: Int -> Bool pReverseUnit x = [x] == myReverse [x] pReverseApp :: [Int]->[Int]->Bool pReverseApp xs ys = myReverse (xs++ys) == (myReverse ys) ++ (myReverse xs) -- append append :: [a]->[a]->[a] --append [] ys = ys --append (x:xs) ys = x:(append xs ys) append xs ys = foldr (:) ys xs pAppendUnit :: [Int]-> Bool pAppendUnit x = (append [] x) == x pAppendApp :: [Int]->[Int]->Property pAppendApp xs ys = not (null xs) ==> let hd = head xs tl = tail xs in (append xs ys) == hd:(append tl ys) main = quickCheck pLengthUnit >> quickCheck pLengthApp >> quickCheck pReverseUnit >> quickCheck pReverseApp >> quickCheck pAppendUnit >> quickCheck pAppendApp