論文要約/How to specify it!
Springer Link
1. Introduction
本論文ではproperty-based testingの方法について論じている。
property-based testingとは、
Historically the definition of property-based testing has been “The thingthat QuickCheck does”.
概ね、あらゆる値に対して普遍的な性質を述べることで、性質に対して与えられるデータ、または関数がそれを満たせるようになっているかをチェックするテスト手法のことである。
2. A Primer in Property-Based Testing
伝統的なユニットテストでは、
code:haskell
testReverse = reverse 1, 2, 3 === 3, 2, 1
のようなテストケースを書く。
これをパスすれば一見 reverse 関数は正しく実装されているように思える。しかし reverse が常に [3, 2, 1] というリストを返す実装だった場合、このテストは有効ではない。
ではあらゆる値に対して reverse が正しく動くことをテストしたい。reverse に渡る引数をパラメタライズした 性質を記述すると、
code:haskell
prop_Reverse :: Int -> Property
prop_Reverse xs = reverse xs === ???
こう書けそうだ。
しかし ??? には何が入るんだろう。
code:haskell
prop_Reverse :: Int -> Property
prop_Reverse xs = reverse xs === predictRev xs
reverse が返しうる値を predictRev で実装してみると…これはreverse と同じ実装にせざるを得ない。
ではどうするか? reverse の返す値に直接言及しないことでこの問題を回避する。
code:haskell
prop_ReverseReverse :: Int -> Property
prop_ReverseReverse xs = reverse (reverse xs) === xs
一見よさそうだが、reverse がこのように実装されていると、
code:haskell
reverse xs = xs
次のテストは通ってしまう。
code:haskell
prop_Wrong :: Int -> Property
prop_Wrong xs = reverse xs === xs
code:console
*Examples> quickCheck prop_Wrong
*** Failed! Falsified (after 5 tests and 3 shrinks):
0,1
1,0 /= 0,1
ところでQuickCheckはランダムに生成したテストケースを縮小していき(shrinking)、できるだけ小さい反例を探してくれる。
4. Approaches to Writing Properties
4.1. Validity Testing
4.2. Postconditions
4.3. Metamorphic Properties
4.4. Inductive Testing
4.5. Model-based Properties
あわせて読みたい
Philip Wadler. Theorems for free!.
型によりタダで手に入る定理達。まず型が存在するということは何なのか、という感覚が養える。