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

(注意,某些测试用例可能被分配了多个标签)

我认为这回答了从 test.check 设计页面来的问题“我们如何收集关于生成物类型的数据的统计信息?”

13 个答案

0

由:nberger 评论

这些补丁在介绍 reporter-fn 之后不再适用。

在我处理新补丁的同时,我想知道其他人的(尤其是 gfredericks)关于在 test.check 中引入这个新 :labels 概念的看法。每个试验的结果映射可以可选地包含一些 :labels,这些标签包含在 :complete 报告中,以便进行计算。

另一种方法是实现一个作为外部库/报告器的统计功能,但要实现这一点,我们需要保留每个试验结果映射中的任意状态,以便累积标签。或者,我们也许可以使 (reporter-fn :type :trial ...) 包含整个结果映射,从而使报告器函数有机会“保存”这种状态,但这种方法看起来并不优雅...

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)}}:它只用参数向量为标签。
  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发表的评论:

我也应该牢记,这可能与我之前在设计页面 http://dev.clojure.org/display/design/test.check 中解决的 "测试失败反馈" 问题有关联: http://dev.clojure.org/display/design/test.check

0

由gfredericks发表的评论:

我也应该牢记,这可能与我之前在设计页面 http://dev.clojure.org/display/design/test.check 中解决的 "测试失败反馈" 问题有关联: 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 评论

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

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

这个补丁有什么阻碍吗?

...