5

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

谢谢!

4

4 回答 4

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

元组的第二个组成部分与测试用例的大小有关,但我忘记了具体是什么。

于 2013-10-04T19:50:50.927 回答
3

使用quickCheckWith功能

quickCheckWith (stdArgs{replay = Just (myNewGen, testSize)}) property

如果你有一个失败的测试并且你想重用它,

result <- quickCheckResult failing_prop
let gen = usedSeed result
let size = usedSize result

获得在失败测试中使用的大小和种子。

由于您还需要可重现的错误,因此一个好的收缩算法可能会有所帮助。默认情况下,它会返回[]但提供了一个足够好的结果,那么即使在不同的随机运行中,您也可能会遇到相同(最小)的失败。

于 2013-10-04T19:51:25.477 回答
1

QuickCheck >= 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)
        }
于 2014-10-28T15:04:31.513 回答
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)

于 2013-10-04T21:47:41.687 回答