【问题标题】:How does Clojure spec differ from property-based testing libraries, such as Haskell QuickCheck?Clojure 规范与基于属性的测试库(例如 Haskell QuickCheck)有何不同?
【发布时间】:2018-03-30 21:16:22
【问题描述】:

其他语言有基于属性的测试库,例如Haskell QuickCheckClojure spec 与此类库有何不同?或者它只是Clojure 的基于属性的测试框架?

【问题讨论】:

标签: testing clojure clojure.spec property-based-testing


【解决方案1】:

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)

s/fdef 规范定义了我们希望函数的 属性:它接受一个字符串,返回一个字符串,返回的字符串应该是输入的两倍。我们使用check 来确保这些属性适用于一堆随机生成的输入。

查看overviewguide 了解更多信息。

【讨论】:

  • spec 与test.check 的区别仅在于它能够自动创建测试生成器吗?这也是规范与 QuickCheck 的区别吗?您能否介绍一些规范在测试之外使用的示例?
  • 没有理由比较 clojure.spec 与 test.check 或任何其他基于属性的测试库;除了测试之外,它还有许多用途和目的,其核心是为数据结构编写规范。链接的概述很好地解释了这一点,链接的指南有许多测试之外的规范使用示例。
  • 当您说数据结构的规范时,您是指供人类消费吗?或者程序可以用它做些什么(除了测试)?
  • 是的,规范是人类和机器可读的。例如,程序可以使用规范来断言某些数据(可能是用户输入)符合规范。在此基础上,有像 Expound 这样的库可以以更易于阅读的格式呈现规范问题。然后是Phrase,用于将规范问题转化为最终用户友好的消息。
  • 简而言之,规范的目标是创建可用于测试和人类消费的规范(有一些工具可以使它们更易于阅读)。与其他工具(QuickCheck 等)相比,规范更具表现力,允许使用描述代替文本规范。我做对了吗?
猜你喜欢
  • 1970-01-01
  • 2014-05-07
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
相关资源
最近更新 更多