I couldn't find anything in the QuickCheck API to do this in a nice way, but here's something I hacked together using the monadic QuickCheck API. It intercepts and logs the inputs to your property in an IORef
, and assumes that if it failed, the last one was the culprit and returns it in a Just
. If the test passed, the result is Nothing
. This can probably be refined a bit but for simple one-argument properties it should do the job.
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"