分享您的想法,请点击2024 Clojure 状态调查!

欢迎!请查看关于页面,了解更多关于这里如何工作的信息。

0
Spec

在尝试手动将 clojure.test 和 spec 连接到 fdef'ed 函数时,我意识到 spec.test/check 返回一个对于失败测试为 (link: :failure false) 的映射。我(几乎)确定它应该返回 true,因为 spec.test/abbrev-result 接收 spec.test/check 的返回值作为参数,并测试 :failure 的值。我没有生成一个 spec.test/check 对于失败测试返回 (link: :failure true) 的情况。作为信息,它返回一个没有 :failure 键的映射,用于通过测试。

以下是一个简单的在 REPL 中复现的情况:

(defn foo-fn (link: x) "bar")

(s/fdef foo-fn

    :args (s/cat :x any?)
    :ret string?)

(stest/check `foo-fn) ;; => 无错误,正常的小映射打印,没有 :failure 条目

(defn foo-fn (link: x) 1)

(stest/check `foo-fn) ;; => 完整错误映射,:failure 等于 false。:failure 显示如下

(-> (stest/check `foo-fn) first :failure) ;; => false

9 个答案

0

评论者:gfredericks

这虽然有些令人困惑,但并不是一个错误。

{{stest/check}} 正在通过 (至少部分地) 将 {{clojure.test.check/quickcheck}} 的返回值传递下去,{{clojure.test.check/quickcheck}} 返回属性评估的真实性,以确定通过还是失败。由于非真值可以是{{false}}或{{nil}},查看它并不会让我们学到多少(尽管 {{:failure}} 键下也可能有一个异常,这样会更具有信息性)。

test.check 的下一个版本应该有一个更实用且更容易理解的提取测试信息的方式,但我不知道当使用 {{stest/check}} 时的样子会是怎样的。

0

评论人:djebbz

我仍然不明白为什么你们不认为这是一个错误。`stest/check`的文档字符串说 “:failure可选择测试失败”。我期望只有当测试失败时才有一个:failure键(因此是可选择性的),并包含一些有用的信息。

我在使用stest/abbrev-result来显示`stest/check`的输出,它期望:failure为真值来显示所有有用的失败信息。如果`stest/check`返回false,我认为这是不匹配的,是一个错误。`stest/abbrev-result`的文档字符串明确说明了它将检查的结果作为参数接收,所以我并不是将方钉强行塞入圆孔。

感谢您如此迅速地回答我,并抽出宝贵时间。

0
评论人:grzm_

:failurefalse的值确实很令人困惑。stest/abbrev-result{{:failure false}}中*非常*令人困惑,因为它没有像[djebbz]指出的那样提供通常的失败信息。

https://github.com/clojure/spec.alpha/blob/2824ad49df8deadcb4b75acdf624e732a85b4ac7/src/main/clojure/clojure/spec/test/alpha.clj#L438-L446}
(defn abbrev-result
  "给定一个检查结果,返回一个适合总结使用的缩略版本。"
suitable for summary use."
  [x]
  (if (:failure x)
    (-> (dissoc x ::stc/ret)
                       )(update :spec s/describe)
                       (update :failure unwrap-failure))
    (dissoc x :spec ::stc/ret)))


以下是一个示例,说明了它可能有多大的误导性


(require '[clojure.spec.alpha :as s]
             '[clojure.spec.test.alpha :as stest])

(alias 'stc 'clojure.spec.test.check)

(defn adder [a b]
  (+ a b))

(s/fdef adder
        :args (s/cat :a int? :b int?)
        :ret string?)

(-> (stest/check `adder) first stest/abbrev-result)
;; => {:sym ex.check-test/adder, :failure false}

;; 编写`abbrev-result`的替代版本,检查`true`
;;...

(defn- failure-type [x] (::s/failure (ex-data x)))
(defn- unwrap-failure [x] (if (failure-type x) (ex-data x) x))

(defn- abbrev-result [x]
  (let [failure (:failure x)]
    ;(if-not (or (true? failure)
                              )
      (-> (dissoc x ::stc/ret)
                       )(update :spec s/describe)
                       (update :failure unwrap-failure))
                       (dissoc x :spec ::stc/ret))))

(-> (stest/check `adder) first abbrev-result)
;; => {:spec (fspec :args (cat :a int? :b int?) :ret string? :fn nil),
;;     :sym ex.check-test/adder,
;;     :failure false}


再次提醒,任何真值{{:failure}}都将提供额外的详细信息,而假值{{:failure}}则不会。

我理解了不改变 {{:failure}} 键值的动机。如果这个值将要保持不变,我认为应该更新 {{stest/abbrev-result}} 以便于显式测试 {{nil}} 和 {{true}},而不是为了与 {{stest/check}} 的结果保持一致而测试 truthy。

0

评论人:djebbz

非常感谢米歇尔。最后,我采取了一个小变化,我没有进行 (dissoc x ::stc/ret) 而是保留整个检查结果,因为它包含了堆栈跟踪、spec/explain-data 映射、缩小的失败用例等。

0

评论者:grzm

看起来 {{abbrev-result}} 应该使用 {{result-type}} 来测试是否通过。附上一段补丁代码,如果需要的话,我也愿意重新提交。

编辑:我太草率了。我会调查并重新提交。抱歉带来麻烦。

编辑2:我再次怀疑自己的判断,但第一次判断是正确的。我非常确信第一次是对的。我认为补丁是好的。

0

评论者:gfredericks

注意,在 test.check 主分支上有未发布的变化,这些变化可能影响此处最佳的做法。特别是(链接:https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/results.cljc 文本:这些东西)。

0
评论人:grzm_

谢谢,[~gfredericks]。结果协议是一块需要注意的地方。我认为在 {{abbrev-result}} 这个层面上使用 {{result-type}} 是正确的抽象。我认为在 {{make-check-result}} 中装饰 {{quick-check}} 结果时应该使用 {{Result/passing?}} 代替 [{{(true? result)}}|https://github.com/clojure/spec.alpha/blob/2824ad49df8deadcb4b75acdf624e732a85b4ac7/src/main/clojure/clojure/spec/test/alpha.clj#L319]. 你明白我的意思吗?
0

评论者:gfredericks

是的,我认为是这样。但是,现在我已经审查了规格代码,看到了有多少细节关于返回值被依赖(这可能是对其他test.check用户,而且不应该让我感到惊讶),我想我将会为{{quick-check-2}}保留结果协议的细节(链接:TCHECK-142 文本:https://dev.clojure.org/jira/browse/TCHECK-142))。

0
参考: https://clojure.atlassian.net/browse/CLJ-2246 (由 alex+import 报告)
...