Библиотека 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 рассматривает свойство как неисправное и пытается уменьшить ввод, вызвавший сбой. Затем этот процесс сжатия не запускается с ограничением по времени, в результате чего общее время, используемое для вычислений, превышает установленный предел времени.
Можно подумать, что я мог бы использовать комбинатор QuickCheck within
для ограничения времени вычислений. (within
рассматривает свойство как неудавшееся, если оно не завершается в течение заданного срока.) Однако within
не совсем делает то, что мне нужно, поскольку QuickCheck по-прежнему пытается уменьшить входные данные, вызвавшие сбой, процесс, который может занять слишком много времени. (В качестве альтернативы мне могла бы подойти версия within
, которая не позволяет QuickCheck сжать входные данные до свойства, которое не удалось, потому что оно не завершилось в течение заданного срока.)
Как я могу запретить QuickCheck перехватывать все исключения?