请在2024 Clojure 状态调查!中分享你的想法。

欢迎!请参考关于页面以了解更多关于此功能的信息。

0
test.check

灵感来自 Haskell 的 QuickCheck 中的类似功能。添加了一个 {{classify}} 函数,这个函数 intends to be used as a wrapper of {{prop/for-all}},返回一个合适的属性(生成器),适用于 {{test.check/quick-check}},这样可以增强底层属性返回的结果映射,在 {{:labels}} 键下添加收集到的标签。也触发了 {{default-reporter-fn}} 中的新事件 {{:stats}},默认实现调用 {{test.check.stats/print}},按以下格式打印试验分类:

12.7% :lt-30 14.5% :gte-30 29.1% :lt-30, :lt-20 43.6% :lt-30, :lt-10, :lt-20

(注意,某些测试案例可能会分配多个标签)

我认为这回答了测试.check 设计页面中“我们如何收集生成物类型的统计信息?”这个问题

13 答案

0

评论者:nberger

在此修复程序不再适用于 reporters 函数引入之后。

当我修复新故障时,我想了解其他人(特别是 gfredericks)对 test.check 中新 :labels 概念的看法。每次试验的结果映射可以可选地包括一些 :labels,这些标签包含在 :complete 报告中,以便计算统计信息。

另一种方法是实现一个作为外部库/reporter 的统计信息,但要做到这一点,我们需要 trials 循环保持每个试验结果映射中的任意状态,以便我们可以累计标签。或者,也许我们可以使 (reporter-fn :type :trial ...) 包含整个结果映射,这样 report-fn 就有机会“保存”此状态,但这种方式看起来并不很优雅...

0

评论由:gfredericks 发布

需要思考的事情

  • 统计只与参数有关,所以有必要整个包裹属性吗?
    尽管 Haskell 是这样做的
  • 另一方面,我喜欢将统计作为 {{check}} 命名空间中通用特性的特定实例的想法,但当前的实现并没有完全实现这一点,因为我们在 {{check}} 命名空间中有大量的标签内容
  • 但是这很困难将其移出,因为如果 {{check}} 只暴露了通用 reduce 功能,那么直接访问 {{quick-check}} 的用户将需要提供两件事情——一个包裹的属性,以及适当的 reduce 函数
0

评论者:nberger

上传了一个新的补丁,利用了新的 reporter-fn 机制。

在这个新的补丁中,一些内容被简化了

  • 移除了将用作启用/禁用每个测试中统计打印的新 * } var。默认-reporter-fn 将现在只在结果映射中有标签时打印统计。要打印统计,只需使用不同 :reporter-fn 不打印统计即可。
  • 在统计报告中,现在只打印带有标签的行。在上一个版本中,有一个带有 "无标签" 试验百分比的行。我现在移除了它,以减少冗余。

还添加了文档字符串,确保统计在 clojurescript 和其他方面有所改进。

0

评论者:nberger

我认为为试验分配标签提供更多方式会很不错。例如

  1. {{(classify prop)}}: 只是使用 args 的向量作为标签。
  2. {{(classify prop label-fn)}}: 通过对 args 应用 {{label-fn}} 获取标签。例如:{{(classify prop count)}} - 将 arg(向量、字符串等)的计数作为标签分配
  3. {{(classify prop label-fn pred)}}: 只有当 {{pred}} 产生真值时才应用 {{label-fn}}。例如:`
  4. {{(classify prop pred)}}: 使用 args 的向量作为标签,但只有当 {{pred}} 产生真值时。例如:`(classify prop #(<= count%)` - 当计数小于或等于 1 时分配 arg 的计数作为标签
  5. {{(classify prop pred)}}: 这是当前的签名人。只有当 pred 产生真值时才分配标签

因此,我考虑将签名改为接收一个包含 {{(:pred :label-fn :label)}} 可选键的映射。这三个键是可选的。{{:label}} 和 {{:label-fn}} 不能同时存在。

根据我的理解,Haskell QuickCheck (https://hackage.haskell.org/package/QuickCheck-2.8.2/docs/Test-QuickCheck-Property.html) 提供了不同的函数来提供相似的替代方案
{{(classify prop)}} 将与 Haskell QC 中的 {{collect}} 类似
{{(classify prop label-fn)}} 将与 Haskell QC 中的 {{label}} 类似
{{(classify prop label-fn pred)}} 将与 Haskell QC 中的 {{classify}} 类似

您怎么看呢,@gfredericks?

0

评论由:gfredericks 发布

在讨论后,我的直觉是 2 和 5 最为自然,也许可以将 2 命名为 {{collect}} 以反映 Haskell 版本的命名。

我们讨论了是否将 {{nil}} 作为在 {{collect}} 中不进行标注的标志,但我不太喜欢这个想法。

0

评论由:gfredericks 发布

我还应该记得,这可能与其他更改重叠,以解决 clojure 页面上的 "Test Failure Feedback" 问题:http://dev.clojure.org/display/design/test.check

0

评论由:gfredericks 发布

我还应该记得,这可能与其他更改重叠,以解决 clojure 页面上的 "Test Failure Feedback" 问题:http://dev.clojure.org/display/design/test.check

0

评论者:nberger

bq. 我们讨论了是否将 nil 作为在 collect 中不进行标注的标志,但我不太喜欢这个想法。

也许我们可以使用一个命名空间关键字来表示应忽略标签?例如,{{clojure.test.check.stats/ignore}}。这样,我们就可以通过创建一个当 pred 不匹配时返回 {{stats/ignore}} 的函数,在 collect 中通过 term 实现分类。

`
(defn collect
[prop label-fn]
(gen/fmap

(fn [{:keys [args] :as result-map}]
  (let [label (apply label-fn args)]
    (if (= ::ignore label)
      result-map
      (update result-map :labels conj label))))
prop))

(defn classify
[prop pred label]
(collect prop (fn [& args]

              (if (apply pred args)
                label
                ::ignore))))

`

另一个选择是向 {{collect}} 添加一个额外的参数,以接收关于是否将 nil 作为标签或忽略它的标志。我更喜欢 {{:stats/ignore}}。

0

评论者:nberger

已替换为新补丁,该补丁添加了{{stats/classify}}和{{stats/collect}}两项,如讨论中所述。我认为这个新补丁实现了讨论的内容,涵盖了情况2和5,并且函数名类似于haskell实现,没有对nil进行特殊处理(它是一个有效的标签),并且没有添加如前评论中所建议的{{:stats/ignore}}。

0

评论者:nberger

添加了一个新补丁TCHECK87-add-stats-feature-2.patch,它基于当前的master版本。我认为这还不是最终版本(我希望找到一种方法来避免将标签相关内容污染主quickcheck循环,例如),但是它已经有望接近最终版本。

0

评论者:nberger

添加了新补丁TCHECK87-add-stats-feature-3.patch,它基于当前的master版本并合并了一些提交的修改。同时也修复了ClojureScript中的print-stats测试。

0
参考: https://clojure.atlassian.net/browse/TCHECK-87 (由nberger报告)
0

有什么东西阻碍了这个补丁吗?

...