2024 Clojure现状调查!分享您的想法。

欢迎!请查看关于页面以了解如何使用此信息。

0
test.check

受到Haskell的QuickCheck中类似功能的启发。添加一个名为{{classify}}的函数,该函数旨在用作{{prop/for-all}}的包装器,返回适合{{test.check/quick-check}}的属性(生成器),并将底层属性的返回结果的-map增量为带有{{: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)在这个测试.check中是否应该有这个新的:labels概念。每个试验的结果-map可以可选地包括一些:labels,这些:labels包含在:complete报告里,以便计算统计数据。

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

0

评论者:gfredericks

需要考虑的事项

  • 统计仅是参数的函数,因此是否需要包装整个属性呢?
    但是haskell这样做
  • 另一方面,我认为将统计作为一个特定实例的通用特性,这个想法很好,但是目前的实现并没有实现这一点,因为我们有很多标签内容在 {{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}} 返回真值时
  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 版本保持一致。

我们还讨论了 maybe 将 {{nil}} 作为 {{collect}} 中不标记的标志进行治疗,但我个人并不特别喜欢这个想法。

0

评论者:gfredericks

我也不应该忘记,这可能与对“测试失败反馈”问题的处理更改重叠,可参见 confluence 页面: http://dev.clojure.org/display/design/test.check

0

评论者:gfredericks

我也不应该忘记,这可能与对“测试失败反馈”问题的处理更改重叠,可参见 confluence 页面: http://dev.clojure.org/display/design/test.check

0

评论者:nberger

bq. 我们讨论了 maybe 将 nil 作为 collect 中不标记的标志进行治疗,但我个人并不特别喜欢这个想法。

或许我们可以使用一个命名空间关键字来指示应该忽略标签?比如 {{clojure.test.check.stats/ignore}}。这样我们就可以通过创建一个在 pred 不匹配时返回 {{stats/ignore}} 的函数, easy 地将 {{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
by

评论者:nberger

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

0
by

评论者:nberger

增加了一个新的补丁TCHECK87-add-stats-feature-3.patch,基于当前master,并对一些合并提交进行了简化。同时也修复了ClojureScript中的print-stats测试。

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

有什么阻止这个补丁的吗?

...