在clojure中使用生成测试库,使用更高阶函数构建自己的库

opt*_*evo 3 clojure generative-testing

Clojure有许多用于生成测试的库,例如test.check,test.generativedata.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)
Run Code Online (Sandbox Code Playgroud)

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

是否存在任何生成库可以做的事情,而不仅仅是(或更多)通过编写一些更高阶函数可以简洁地实现?

作为stackoverflow众神的旁注:我不相信这个问题是主观的.我不是要求哪个库更好.我想知道任何/所有数据生成库的哪些特定特征或技术将它们与组成香草高阶函数区分开来.一个示例答案应该说明使用任何库生成随机数据,并解释为什么通过以上面说明的方式组合HOF来做更复杂的事情.

ama*_*loy 5

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

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