每次运行“quickCheck prop_xyz”时,都会使用新的随机种子。如何强制QuickCheck始终使用相同的随机种子?
谢谢!
答案 0 :(得分:5)
您需要的功能在Test.QuickCheck
;使用quickCheckWith
指定自定义Args
。特别是,replay :: Maybe (StdGen, Int)
字段允许您重放测试。因此,您可以使用stdArgs
默认值并进行调整;例如,
ghci> :load Main.hs
ghci> import Test.QuickCheck
ghci> import System.Random -- for mkStdGen
ghci> quickCheckWith stdArgs{replay = Just (mkStdGen 42, 0)} prop_xyz
元组的第二个组成部分与测试用例的大小有关,但我确实忘记了。
答案 1 :(得分:3)
使用quickCheckWith
功能
quickCheckWith (stdArgs{replay = Just (myNewGen, testSize)}) property
如果您的测试失败并且您想重复使用它,
result <- quickCheckResult failing_prop
let gen = usedSeed result
let size = usedSize result
获取失败测试中使用的大小和种子。
由于您还需要可重现的错误,因此良好的缩小算法可能会有所帮助。默认情况下,它返回[]
但提供足够好的一个,然后即使在不同的随机运行中也可以最终得到相同的(最小)失败。
答案 2 :(得分:0)
如果您想确定导致失败的Generator
,您可以执行以下操作:
import Test.QuickCheck
import System.Random
reproducableTest :: Testable a => a -> Maybe (StdGen, Int) -> IO ()
reproducableTest prop repl = do result <- quickCheckWithResult stdArgs{replay = repl} prop
case result of
Failure{interrupted = False} -> do putStrLn $ "Use " ++ show (usedSeed result) ++ " as the initial seed"
putStrLn $ "Use " ++ show (usedSize result) ++ " as the initial size"
_ -> return ()
只应将两个种子数中的第一个用作函数的参数。
因此,如果您拥有自己的财产prop
,则您的初始通话将为reproducableTest prop Nothing
。你会得到像
Use x y as the initial seed
Use z as the initial size
然后你会再次使用reproducableTest prop $ Just (mkStdGen x , z)
答案 3 :(得分:0)
QuickCheck示例&gt; = 2.7和tf-random。
如果失败的测试运行的输出如下所示:
Failure {
usedSeed = TFGenR 1CE4E8B15F9197B60EE70803C62388671B62D6F88720288F5339F7EC521FEBC4 0 70368744177663 46 0,
USEDSIZE = 75,
...
}
然后您可以按如下方式重现失败:
import Test.QuickCheck.Random (QCGen(..))
import System.Random.TF (TFGen)
qcheck :: Testable a => a -> IO ()
qcheck prop = quickCheckWith args prop
where
usedSeed = QCGen (read "TFGenR 1CE4E8B15F9197B60EE70803C62388671B62D6F88720288F5339F7EC521FEBC4 0 70368744177663 46 0"::TFGen)
usedSize = 75
args = stdArgs{
replay=Just(usedSeed, usedSize)
}