首页 > 解决方案 > 如何使用 QuickCheck 在 Haskell 中进行迭代测试?

问题描述

你如何在 Haskell QuickCheck 中生成一个随机实例,然后在这个实例上运行进一步的测试?

让我举个例子来说明。在下面的代码片段中,我生成了一个Int,然后想要对此非常运行进一步的测试Int

{-# OPTIONS -Wall #-}

import           Test.Tasty
import           Test.Tasty.QuickCheck as QC
import qualified Debug.Trace as Trace

main :: IO()
main = defaultMain tests

test1 :: Int -> Property
test1 i = withMaxSuccess 2 (test2 i)

test2 :: Int -> (Int, Int) -> Property
test2 i (a, b) =
  Trace.trace ("(n,a,b) = " ++ show (i, a, b)) $
  property True

tests :: TestTree
tests =
  testGroup
  "Test suite"
  [
    QC.testProperty "Test" (withMaxSuccess 3 test1)
  ]

作为输出,我想要类似的东西:

(n,a,b) = (0,0,0)
(n,a,b) = (0,1,2)
(n,a,b) = (-1,-1,-1)
(n,a,b) = (-1,-2,-3)
(n,a,b) = (2,0,-2)
(n,a,b) = (2,1,-1)

但相反,我得到:

(n,a,b) = (0,0,0)
(n,a,b) = (-1,-1,-1)
(n,a,b) = (2,0,-2)

我找到了这篇文章(如何 QuickCheck 测试每个样本的所有属性),但它并没有真正帮助我。

标签: haskelltestingquickcheck

解决方案


考虑withMaxSuccess函数:

withMaxSuccess :: Testable prop => Int -> prop -> Property

这是一个接受 anyTestable并将其转换为Property. 结果Property的行为是它将运行Int.

test1函数是一个Testable实例。当您调用时,withMaxSuccess 3 test1您会更改 的行为test1,以便它在运行时最多运行 3 次。

虽然test1返回 aProperty的行为仅运行两次 ( withMaxSuccess 2),但它会被 覆盖withMaxSuccess 3

withMaxSuccess函数不运行测试,它只是更改属性的定义。withMaxSuccess 3是该属性的最新修改,因此您看到它运行了 3 次。


推荐阅读