Библиотека 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 перехватить все исключения?