QuickCheck ライブラリは、プロパティのテスト時にスローされるすべての例外をキャッチするようです。特に、この動作により、QuickCheck の計算全体に時間制限を設けることができなくなります。例えば:
module QuickCheckTimeout where
import System.Timeout (timeout)
import Control.Concurrent (threadDelay)
import Test.QuickCheck (quickCheck, within, Property)
import Test.QuickCheck.Monadic (monadicIO, run, assert)
-- use threadDelay to simulate a slow computation
prop_slow_plus_zero_right_identity :: Int -> Property
prop_slow_plus_zero_right_identity i = monadicIO $ do
run (threadDelay (100000 * i))
assert (i + 0 == i)
runTests :: IO ()
runTests = do
result <- timeout 3000000 (quickCheck prop_slow_plus_zero_right_identity)
case result of
Nothing -> putStrLn "timed out!"
Just _ -> putStrLn "completed!"
QuickCheck はすべての例外をキャッチするため、timeout
ブレークします: 実際に計算を中止するわけではありません! 代わりに、QuickCheck はプロパティが失敗したものとして扱い、失敗の原因となった入力を縮小しようとします。この縮小プロセスは時間制限付きで実行されないため、計算に使用される合計時間が規定の時間制限を超えます。
within
QuickCheck のコンビネータを使用して計算時間を制限できると考える人もいるかもしれません。(within
指定された制限時間内に終了しない場合、プロパティは失敗したものとして扱います。)ただし、within
QuickCheckは失敗の原因となった入力を縮小しようとするため、プロセスに時間がかかる可能性があるため、私が望むことはできません。長すぎる。(代わりに機能するwithin
のは、指定された制限時間内に終了しなかったために失敗したプロパティへの入力を QuickCheck が縮小しようとするのを防ぐバージョンです。)
QuickCheck がすべての例外をキャッチしないようにするにはどうすればよいですか?