【问题标题】:Generate new test data inside QuickCheck property在 QuickCheck 属性中生成新的测试数据
【发布时间】:2014-02-25 21:31:03
【问题描述】:

我在这里遇到了编程问题。一半的麻烦是问题本身很难思考,另一半是我不记得如何找到解决 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 在某处有一个函数可以丢弃不满足给定条件的输入。 (唯一的问题是它可能需要不合理的尝试次数才能满足条件......)

有没有办法做到这一点?我盯着黑线鳕页面,但我不知道如何得到我想要的……

【问题讨论】:

    标签: haskell quickcheck


    【解决方案1】:

    属性可以采用以下形式

    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 ==>,如上面的sn-p所示。另一个例子:

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

    你说得对,这个组合器会丢弃不恰当的情况。如果不希望这样做,您可以在输入类型上创建一个 newtype 包装器并为其重新定义 Arbitrary 实例(参见 PositiveNonEmptyhere 的示例)

    【讨论】:

    • 好的,这很好地解释了如何处理生成正确的数据。现在如何在属性中生成新的测试数据?
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 2014-05-07
      相关资源
      最近更新 更多