在QuickCheck属性中生成新的测试数据

时间:2014-02-25 12:50:41

标签: haskell quickcheck

我在这里遇到编程问题。问题的一半是问题本身是非常棘手的,另一半是我不记得如何找到我的方式围绕QuickCheck。

我知道如果你编写一个带有几个带Arbitrary实例的参数的函数,QuickCheck会让你使用该方法作为测试。我无法弄清楚的是如何在该方法中生成新的测试参数。我想写点像

prop13 :: Foo -> Bar -> Bool
prop13 foo bar =
  if foobar foo bar
    then fn1 foo
    else newInput $ \ baz -> fn2 foo bar baz

但我无法弄清楚该怎么做。

实际上,不,我想要写的是

prop13 :: Foo -> Bar -> Property
prop13 foo bar =
  if foobar foo bar
    then label "foobar=YES" $ fn1 foo
    else label "foobar=NO"  $ newInput $ \ baz -> fn2 foo bar baz

这样我就可以检查它是不是100%的时间采取一个分支或类似的荒谬。

实际上,如果我能要求baz具有某些特定属性,那将会是多么伟大。我依稀记得QuickCheck在某个地方有一个函数可以丢弃不满足给定条件的输入。 (唯一的问题是可能需要不合理的次数才能满足条件......)

有办法做到这一点吗?我正盯着Haddock页面,但我无法弄清楚如何得到我想要的......

2 个答案:

答案 0 :(得分:4)

  

属性可以采用

形式      

classify <condition> <string>$ <property>

     

例如,

     

prop_Insert x xs = ordered xs ==> classify (ordered (x:xs)) "at-head" $ classify (ordered (xs ++ [x])) "at-tail" $ ordered (insert x xs) where types = x :: Int

     

为满足条件的测试用例分配了分类   给出,并在之后报告分类的分布   测试。在这种情况下,结果是

     

Main> quickCheck prop_Insert OK, passed 100 tests. 58% at-head, at-tail. 22% at-tail. 4% at-head.

     

请注意,测试用例可能属于多个分类。

(来自QuickCheck manual

要求输入数据的特定属性,您可以在测试正文之前添加somePredicate data ==>,如上面的代码段所示。另一个例子:

prop_max xs = (not . null xs) ==> head (sort xs) == maximum xs

你是对的,这个组合器抛弃了不适当的情况。如果这是不受欢迎的,您可以在输入类型上创建newtype包装,并为其重新定义Arbitrary实例(请参阅PositiveNonEmpty等示例{{3 }})

答案 1 :(得分:4)

我在another answer找到了答案。显然它是forAll

else forAll arbitrary $ \ baz -> fn2 foo bar baz

我只是不记得该怎么做......

(这也有一个很好的功能,允许我指定一个特定的随机数据生成器。)