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}} 键异常,这也更具有信息性) learn little.

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}}}中*非常混淆*,因为它不提供失败通常提供的信息。

{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}

;; 写一个检查`true`的`abbrev-result`的替代版本


(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 null),
;;     :sym ex.check-test/adder,
;;     :failure false}


再次注意,任何*真正的*{{:failure}}值都将会提供附加的详细信息,而假的{{: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 报告)
...