请在 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`,这会产生不匹配,我将其视为错误。《code>stest/abbrev-result` 的文档字符串明确说明,它接收检查的结果作为参数,因此我没有生搬硬套。

感谢您迅速回复,并感谢您的宝贵时间。

0
_评论者:grzm_

{{:failure}} 的 {{false}} 值确实令人困惑。《code>stest/abbrev-result` 在 {{{:failure false}}} 中也是非常令人困惑的,因为它没有提供如 [~djebbz] 所指出的通常失败时的额外信息。

{code:title=https://github.com/clojure/spec.alpha/blob/2824ad49df8deadcb4b75acdf624e732a85b4ac7/src/main/clojure/clojure/spec/test/alpha.clj#L438-L446}
(defn abbrev-result
  "给定一个检查结果,返回适合总结使用的缩略版本。"

  [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)
               (nil? 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}}的结果保持一致。

0

评论者:djebbz

非常感谢Michael。最后,我选择了一个小调整,在这个调整中,我不对{{(dissoc x ::stc/ret)}}进行操作,而是保留整个检查结果,因为它包括堆栈跟踪、spec/explain-data映射、缩小的失败案例等。

0

评论由:grzm发布

看起来{{abbrev-result}}应该使用{{result-type}}来测试检查是否通过。附上一个补丁,它执行这个操作。如果您希望测试伴随它,我很乐意重新提交。

编辑:是的,太急了。我会进行调查并重新提交。很抱歉造成噪音。

编辑2:我对自己的第一反应有误。我相当确信我第一次是正确的。我认为该补丁很好。

0

评论者:gfredericks

请注意,在test.check的master分支上存在未发布的更改,可能会影响这里最佳的做法。具体来说,特别是在以下链接中的内容:[https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/results.cljc text:这些内容]

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]调用。这对你有sense吗?
0

评论者:gfredericks

是的,我认为是这样。但既然我已经审查了规范代码,并看到有多少关于返回值的附带细节被依赖(这很可能也适用于其他test.check用户,不应该让我感到惊讶),我认为我将为{{quick-check-2}}保存Result协议的详细信息(链接:TCHECK-142 文本:https://dev.clojure.org/jira/browse/TCHECK-142)。

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