2
votes

When a QuickCheck test fails, sometimes I need to walk through the code in ghci (or stack repl) to analyse the problem. So the first thing I do is recreate the failing input. Now QuickCheck prints out the failing input (using Show), but sometimes re-creating the input from this is difficult or impossible. For example, the type in question might not implement Read. Or it might be a really complex type which requires lots of types in order to recreate it, and tracking down the modules that export those types, and manually importing them into the repl is a hassle.

So I'd like to be able to recreate the failing input from the seed, which is also reported by QuickCheck. It looks like unGen in Test.QuickCheck.Gen is designed for this.

unGen :: QCGen -> Int -> a

Run the generator on a particular seed. If you just want to get a random value out, consider using generate.

But unGen takes two input parameters. I'm guessing the second one is the seed. How do I recreate the QCGen parameter? Here's an example I tried where the seed was -4346962096583255693. unGen doesn't seem to like a negative seed, so I must be doing something wrong.

λ> (unGen arbitrary) (mkQCGen 0) (-4346962096583255693) :: ImprintEmptyBrainTestData 
ImprintEmptyBrainTestData (*** Exception: Negative exponent
2

2 Answers

3
votes

You should use quickCheckResult (or quickCheckWithResult) to run your tests. In case it returns a Failure, the usedSeed and usedSize fields have the QCGen and Int values you need to pass in the Args to quickCheckWith.

1
votes

There is also a package quickcheck-with-counterexamples where properties can capture generated values for further inspection if a test fails.