从种子为 QuickCheck 重新创建失败的输入值

Recreating failing input value for QuickCheck from a seed

当QuickCheck测试失败时,有时我需要遍历ghci(或stack repl)中的代码来分析问题。所以我做的第一件事就是重新创建失败的输入。现在 QuickCheck 打印出失败的输入(使用 Show),但有时很难或不可能从中重新创建输入。例如,所讨论的类型可能不会实现 Read。或者它可能是一个非常复杂的类型,需要很多类型才能重新创建它,跟踪导出这些类型的模块,然后手动将它们导入 repl 是一件麻烦事。

所以我希望能够从种子 中重新创建失败的输入,这也由 QuickCheck 报告。看起来 Test.QuickCheck.Gen 中的 unGen 就是为此设计的。

unGen :: QCGen -> Int -> a

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

但是unGen需要两个输入参数。我猜第二个是种子。如何重新创建 QCGen 参数?这是我尝试的示例,其中种子为 -4346962096583255693。 unGen好像不太喜欢负种子,所以我一定是做错了。

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

您应该使用 quickCheckResult(或 quickCheckWithResult)来 运行 您的测试。如果 returns 和 FailureusedSeedusedSize 字段具有 QCGenInt 值,您需要在 ArgsquickCheckWith.

还有一个包 quickcheck-with-counterexamples,如果测试失败,属性可以捕获生成的值以供进一步检查。