我使用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
语句。
那么我怎样才能产生三个素数,条件是后两者不如第一个?
答案 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
生成一个值,我们称之为x
。 gen/bind
然后返回(f x)
的值,该值必须是新的生成器。 gen/return
是一个只生成其参数的生成器(所以上面我用它来返回对)。