Clojure spec和基于属性的测试库(例如Haskell QuickCheck)有何不同?

5

2
还可以查看“什么是规范”https://dev59.com/UJfga4cB1Zd3GeqPDPG2#38518300 - nha
1个回答

8

Clojure的QuickCheck类似工具是test.check。Clojure.spec依赖于test.check进行生成测试,但spec不仅限于测试。

Test.check提供了生成测试和基于属性的测试工具。Clojure.spec允许您编写数据的规范,并可以自动从这些规范中创建生成器。如果仅使用test.check,则需要手动创建非平凡的生成器。使用clojure.spec,生成器可以(有一些例外)从您的规范中派生出来。

(s/def ::my-spec string?)       ;; a trivial spec, any string will do
(sgen/sample (s/gen ::my-spec)) ;; create a generator from spec and get samples
;;=> ("" "P" "B" "" "qV" "im4P" "Zf" "" "rL24" "wAV7z")

这些生成器可用于生成您想要测试属性的函数的输入数据。您可以使用test.check编写基于属性的测试,也可以使用clojure.spec为函数编写一些基于属性的测试。以下是一个函数示例,它接受一个字符串并返回“加倍”的字符串:
(defn doubler [s] (str s s))
(s/fdef doubler
        :args (s/cat :s string?)
        :ret string?
        :fn (fn [{:keys [args ret]}]
              (= (* 2 (count (:s args))) (count ret))))
(stest/check `doubler)
< p > s/fdef 规范定义了我们从函数中希望得到的属性:它接受一个字符串,返回一个字符串,而且返回的字符串应该是输入的两倍长。我们使用 check 来确保这些属性对一堆随机生成的输入都成立。

欲了解更多信息,请参阅概述指南


区别于test.check,spec的不同之处仅在于其自动创建测试生成器的能力吗?这也是区别于QuickCheck的吗?您能否提供一些spec在测试以外使用的示例? - dilvan
1
没有理由将clojure.spec与test.check或任何其他基于属性的测试库进行比较;它有许多用途和目的超出了测试,其中核心是编写数据结构的规范。链接的概述很好地解释了这一点,链接的指南中有许多规范用法的示例,超出了测试范畴。 - Taylor Wood
当你说数据结构的规范时,你是指人类使用吗?还是程序可以利用它做些什么(除了测试)? - dilvan
指南中,我找到了关于规范、测试、解释测试结果(规范违规)和生成器的示例。在什么是规范问题中,我发现“符合”是一个值,它可以在测试之外给你一个解析和解构版本的值。 - dilvan
1
是的,规范既可以由人阅读,也可以由机器阅读。例如,程序可以使用规范来断言一些数据(可能是用户输入)符合某个规范。在此基础上,有一些库,比如Expound,可以以更易于人理解的格式呈现规范问题。还有一个叫做Phrase的库,旨在将规范问题转化为用户友好的信息。 - Taylor Wood
1
简而言之,规范目标是创建可用于测试和人类使用的规范(有工具可以使它们更易读)。与其他工具(QuickCheck等)相比,规范更具表现力,允许使用描述来代替文本规范。我理解得对吗? - dilvan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接