2024年度Clojure调查!中分享您的想法。

欢迎!请查看关于页面以了解更多有关本网站的信息。

0
Spec

在尝试手动连接 clojure.test 和 spec 到 fdef'd 函数时,我意识到 spec.test/check 在失败的测试中返回一个包含(链接::failure false)的映射。我(几乎)确定它应该返回 true,因为 spec.test/abbrev-result 会将其参数传递给 spec.test/check,并测试 :failure 的值。我无法构造出任何让 spec.test/check 为失败的测试返回(链接::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

我还是不明白为什么你不认为这是一个bug。`stest/check`的文档字符串说":failure是可选的测试失败"。我期望只有在测试失败时才有一个:failure键(因此称为可选),并包含一些有价值的信息。

我使用`stest/abbrev-result`来显示`stest/check`的输出,它期望`:failure为真时显示所有有价值的失败信息。如果`stest/check`返回`false`,那就是我认为的bug。`stest/abbrev-result`的文档字符串明确说明它接收检查的结果作为参数,所以我并没有把一个方钉放进一个圆孔。

感谢你这么快就回答我,并花费您的宝贵时间。

0
评论由:grzm

`[:failure false]`的值确实很令人困惑。正如[djebbz]指出,`stest/abbrev-result`在`{{:failure false}}`中*非常*令人困惑,因为它没有提供通常应该失败时额外的信息。

https://github.com/clojure/spec.alpha/blob/2824ad49df8deadcb4b75acdf624e732a85b4ac7/src/main/clojure/clojure/spec/test/alpha.clj#L438-L446}
(defn abbrev-result
  "Given a check result, returns an abbreviated version suitable for summary use."
suitable for summary use."
  [x]
  (if (:failure x)
    (-> (dissoc x ::stc/ret)
                   )
                   )
      (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`
;; 法则rawl(l)

(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 (or (true? failure)
                    (nil? failure))
      (-> (dissoc x ::stc/ret)
                 )
             )
      (-> (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}


再次注意,*任何*的 truthsy `:failure` 值都会提供额外的细节,而 falsy `:failure`值则不会。

我理解了为什么不想更改 {{:failure}} 键的值的动机。如果这个值将要保持不变,我认为应该将 {{stest/abbrev-result}} 更新为显式地测试 {{nil}} 和 {{true}},而不是验证其结果为 truthy,以保持与 {{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 文本:<这里的内容>)。

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用户的情况,并且不应该让我感到惊讶),我认为我将保留Result协议的细节 для {{quick-check-2}} ((链接:TCHECK-142 文本:https://dev.clojure.org/jira/browse/TCHECK-142)))。

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