请在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 概念的看法。每个试验的结果映射可以 optionally 包含一些 :labels,这些 :labels 包含在 :complete 报告中,以便可以计算统计信息。

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

0

评论者:gfredericks

需要考虑的事情

  • 统计仅是函数参数的一个函数,因此有必要包装整个属性吗?
    不过,Haskell也是这样做
  • 另一方面,我喜欢将统计作为{{check}}命名空间中通用地特征的一个特定实例的构想,但是当前的实现并没有完全达到这一点,因为我们{{check}}命名空间中有大量标签样式的内容
  • 但是难以将其移出,因为如果{{check}}只暴露一个通用的reduce功能,那么直接访问{{quick-check}}的用户将必须提供两个东西——一个包装过的属性和合适的reduce函数
0

评论由:nberger

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

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

  • 删除了即将用于为每个测试启用/禁用统计打印的新* } var。现在,默认reporter-fn只会在结果-map中存在标签时打印统计。要打印统计之外的内容,只需使用不打印统计的不同: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
by

评论者:gfredericks

经过讨论后,我认为2和5是最自然的选择,也许将2称为{{collect}}以反映Haskell版本。

我们谈论了将{{nil}}作为在{{collect}}中不进行标记的标志的可能性,但我并不特别赞同这个想法。

0
by

评论者:gfredericks

我还应该记住,这可能与在confluence页面上解决“测试失败反馈”问题时的更改重叠:http://dev.clojure.org/display/design/test.check

0
by

评论者:gfredericks

我还应该记住,这可能与在confluence页面上解决“测试失败反馈”问题时的更改重叠:http://dev.clojure.org/display/design/test.check

0
by

评论由:nberger

bq. 我们-talked about是不是把 nil 作为在 collect 中不进行标记的标志,但我并不特别赞同这个想法。

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

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

评论由:nberger

已替换为新补丁,增加了 {{stats/classify}} 和 {{stats/collect}},正如讨论的那样。我认为这个新补丁实现了讨论的内容,覆盖了案例 2 和 5,功能名称与 haskell 实现 类似,没有为 nil(它是一个有效的标签)提供特殊处理,也没有添加我之前评论中建议的 {{:stats/ignore}}。

0
by

评论由:nberger

新增了基于当前 master 的新补丁 TCHECK87-add-stats-feature-2.patch。我认为这不是最终版本(我想找到一种方法,不让标签示例污染主要的 quickcheck 循环,例如),但它已经接近完成了。

0
by

评论由:nberger

新增基于当前 master 的新补丁 TCHECK87-add-stats-feature-3.patch,包含一些压缩提交。还修复了 ClojureScript 中的 print-stats 测试。

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

这个补丁还有什么阻碍吗?

...