No pude encontrar nada en la API de QuickCheck para hacer esto de una manera agradable, pero he aquí algo que pirateé utilizando la API monádica QuickCheck. Se intercepta y registra las entradas a su propiedad en un IORef
, y asume que si falló, el último fue el culpable y lo devuelve en un Just
. Si la prueba pasó, el resultado es Nothing
. Esto probablemente se pueda refinar un poco, pero para las propiedades simples de un argumento, debería hacer el trabajo.
import Control.Monad
import Data.IORef
import Test.QuickCheck
import Test.QuickCheck.Monadic
prop_failIfZero :: Int -> Bool
prop_failIfZero n = n /= 0
quickCheck' :: (Arbitrary a, Show a) => (a -> Bool) -> IO (Maybe a)
quickCheck' prop = do input <- newIORef Nothing
result <- quickCheckWithResult args (logInput input prop)
case result of
Failure {} -> readIORef input
_ -> return Nothing
where
logInput input prop x = monadicIO $ do run $ writeIORef input (Just x)
assert (prop x)
args = stdArgs { chatty = False }
main = do failed <- quickCheck' prop_failIfZero
case failed of
Just x -> putStrLn $ "The input that failed was: " ++ show x
Nothing -> putStrLn "The test passed"
muy inteligente, gracias – Xodarap
Este pequeño truco acaba de hacer que mi experiencia en la depuración de Haskell sea mucho mejor. Gracias –