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

欢迎!有关如何使用此功能的更多信息,请参阅关于页面。

0
test.check

受到 Haskell QuickCheck 中的类似功能启发。添加了一个 {{classify}} 函数,它旨在用作 {{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

在此之后引入 reporter-fn 后,这些补丁不再适用。

当我正在编写新补丁时,我想知道其他人(尤其是 gfredericks)对在 test.check 中拥有这种新的 :labels 概念的看法。每个试验的结果映射可以选择包含一些 :labels,这些标签包含在 :complete 报告中,以便进行统计计算。

另一种选择是实现统计信息作为外部库/报告器,但要实现这一点,我们需要 trials 循环从每个试验的结果映射中保留任意状态,从而可以累积这些标签。或者,我们可能需要将 (reporter-fn :type :trial ...)包括整个结果映射,这样报告器函数就有机会“保存”此状态,但这看起来不是非常优雅...

0

评论由:gfredericks 提供

思考的事项

  • 统计信息仅是参数的函数,因此是否需要将整个属性包裹起来?
    然而,haskell 就是这样做的
  • 另一方面,我喜欢将统计信息作为 {{check}} 命名空间泛型功能特定实例的想法,但当前实现并没有完全实现这一点,因为我们有太多的标签数据在 {{check}} 命名空间中
  • 但是很难将其移除,因为如果 {{check}} 仅暴露了一个泛型 reduce 功能,那么直接访问 {{quick-check}} 的用户将需要提供两件事——一个包裹的属性和正确的 reduce 函数
0
by

评论者:nberger

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

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

  • 删除了将用于启用/禁用每个测试的统计信息打印的新 * } var。默认报告器函数现在仅在结果映射中有标签时打印统计信息。要打印统计信息,请仅使用不打印统计信息的不同 :reporter-fn。
  • 在统计报告中,现在只打印带有标签的行。在前一个版本中,有一个包含“无标签”试验百分比的行。我现在将其删除,以减少冗余。

还增加了文档字符串,确保统计信息在 clojurescript 中工作以及一些小的改进。

0
by

评论者:nberger

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

  1. {{(classify prop)}}: 仅使用参数向量作为标签。
  2. {{(classify prop label-fn)}}: 通过应用 {{label-fn}} 获取标签。例如:{{(classify prop count)}} - 将参数(向量、字符串等)的计数作为标签分配
  3. {{(classify prop label-fn pred)}}: 仅当 {{pred}} 返回真值时,应用 {{label-fn}}。例如:(classify prop count #(> (count %) 1)) - 仅当计数大于 1 时分配参数的计数作为标签。
  4. {{(classify prop pred)}}: 仅当 {{pred}} 返回真值时,使用参数向量作为标签。例如:(classify prop #(<= (count %) 1)) - 仅当时称小于或等于 1 时分配参数的计数作为标签。
  5. {{(classify prop pred label)}}: 这是当前的签名。仅在 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 提供

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

0

评论由:gfredericks 提供

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

0

评论者:nberger

bq. 我们讨论了将nil作为collect中不标记的标志处理的可能性,但我认为我不太喜欢这个想法。

也许我们可以使用一个有名称的空间关键词来表示应该忽略的标签?比如{{clojure.test.check.stats/ignore}}。这样,我们可以通过创建一个函数,当pred不匹配时返回{{stats/ignore}},轻松地将{{classify}}以collect的形式实现。

`
(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

这个补丁有什么瓶颈吗?

...