如何为Haskell的quickCheck函数设置常量种子

时间:2013-10-04 19:41:14

标签: testing haskell random quickcheck

每次运行“quickCheck prop_xyz”时,都会使用新的随机种子。如何强制QuickCheck始终使用相同的随机种子?

谢谢!

4 个答案:

答案 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)
        }