La biblioteca QuickCheck parece captar todas las excepciones que se lanzan al probar una propiedad. En particular, este comportamiento me impide poner un límite de tiempo en todo el cálculo de QuickCheck. Por ejemplo:¿Cómo puedo evitar que QuickCheck capture todas las excepciones?
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!"
Debido QuickCheck captura todas las excepciones, timeout
rompe: en realidad no abortar el cómputo! En cambio, QuickCheck considera que la propiedad ha fallado e intenta reducir la entrada que causó la falla. Este proceso de contracción no se ejecuta con un límite de tiempo, lo que hace que el tiempo total utilizado por el cálculo exceda el límite de tiempo prescrito.
Uno podría pensar que podría usar el combinador within
de QuickCheck para limitar el tiempo de cálculo. (within
considera que una propiedad ha fallado si no termina dentro del límite de tiempo dado.) Sin embargo, within
no hace exactamente lo que quiero, ya que QuickCheck aún intenta reducir la entrada que causó la falla, un proceso que puede tomar demasiado tiempo. (Lo que alternativamente podría funcionar para mí es una versión de within
que impide que QuickCheck reduzca las entradas a una propiedad que falló porque no finalizó dentro del límite de tiempo dado.)
¿Cómo puedo evitar que QuickCheck advierta? todas las excepciones?
upvoted porque esta solución se dirige al caso en particular (es decir, poner un límite de tiempo para el cálculo completo QuickCheck). Mirando por encima del código fuente, parece que QuickCheck está cableado para tratar la excepción UserInterrupt especialmente. Lamentablemente, esta solución no responde completamente a mi pregunta: ¡QuickCheck aún se traga todo menos UserInterrupt! –