如何使用Quickcheck根据以前的元素生成随机元素?

时间:2014-06-27 01:26:24

标签: testing clojure generator quickcheck

我使用QuickCheck在Clojure中进行生成测试。

然而,我并不了解它,而且我常常会做一些令人费解的事情。我需要经常做的一件事就是:

  • 从素数列表中生成第一个素数(到目前为止一直很好)
  • 生成小于第一个素数的第二个素数
  • 生成小于第一个素数的第三个素数

但是我不知道如何使用QuickCheck干净地完成这项工作。

这是一个更简单,更愚蠢的例子,它不起作用:

(prop/for-all [a (gen/choose 1 10)
               b (gen/such-that #(= a %) (gen/choose 1 10))]
                (= a b))

它无法正常工作,因为无法解析 prop/for-all不像let语句。

那么我怎样才能产生三个素数,条件是后两者不如第一个?

1 个答案:

答案 0 :(得分:3)

test.check中,我们可以使用gen/bind作为生成器monad中的绑定运算符,因此我们可以使用它来生成依赖于其他生成器的生成器。

例如,要生成[a b]对,我们必须(>= a b),我们可以使用此生成器:

(def pair-gen (gen/bind (gen/choose 1 10)
                        (fn [a]
                          (gen/bind (gen/choose 1 a)
                                    (fn [b]
                                      (gen/return [a b]))))))

满足自己:

(c/quick-check 10000
               (prop/for-all [[a b] pair-gen]
                 (>= a b)))

gen/bind使用生成器g和函数f。它会从g生成一个值,我们称之为xgen/bind然后返回(f x)的值,该值必须是新的生成器。 gen/return是一个只生成其参数的生成器(所以上面我用它来返回对)。