3

Clojure 有许多用于生成测试的库,例如test.checktest.generationdata.generators

可以使用高阶函数来创建可组合的随机数据生成器,例如:

(defn gen [create-fn content-fn lazy]
  (fn [] (reduce #(create-fn %1 %2) (for [a lazy] (content-fn)))))

(def a (gen str #(rand-nth [\a \b \c]) (range 10)))
(a)

(def b (gen vector #(rand-int 10) (range 2)))
(b)

(def c (gen hash-set b (range (rand-int 10))))
(c)

这只是一个示例,可以使用不同的参数、过滤器、部分等进行修改,以创建非常灵活的数据生成函数。

是否有任何生成库可以通过组合一些高阶函数而不是(或更多)简洁地实现的东西?

作为对stackoverflow之神的旁注:我不相信这个问题是主观的。我不是在征求关于哪个图书馆更好的意见。我想知道任何/所有数据生成库的哪些特定功能或技术将它们与组合普通高阶函数区分开来。一个示例答案应该说明使用任何库生成随机数据,并解释为什么按我上面说明的方式组合 HOF 会更复杂。

4

1 回答 1

5

test.check 这样更好。最值得注意的是,假设您生成一个包含 100 个元素的随机列表,并且您的测试失败:您处理该列表的方式是错误的。现在怎么办?你如何找到基本的错误?它肯定不完全取决于那 100 个输入。您可能可以使用仅包含几个元素的列表来重现它,如果您的基本案例有问题,甚至可以使用空列表来重现它。

使这一切真正有用的特性不是随机生成器,而是这些生成器的“缩小”。一旦 test.check 找到破坏测试的输入,它会尝试尽可能简化输入,同时仍然使测试破坏。对于整数列表,收缩很简单,您可以自己做:删除任何元素,或减少任何元素。即使这样也可能不是真的:选择收缩的顺序可能是一个比我意识到的更难的问题。对于较大的输入,例如从向量到 [string, int, keyword] 的 3 元组的映射列表,您会发现它完全无法管理,而 test.check 已经完成了所有艰苦的工作。

于 2014-10-08T20:31:47.817 回答