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)对test.check中的这一新:labels概念有什么看法。每个试验的结果-map可以选择包含一些:labels,它们包含在:complete报告中,以便可计算统计数据。

另一种选择是实现作为一个外部库/reporter的统计数据,但要实现这一点,我们需要试验循环从每个试验的结果-map中保持任意的状态,我们可以在这里累积标签。或者我们也可以让(reporter-fn :type :trial ...)包含整个结果-map,这样reporter-fn就有机会“保存”这种状态,但这种方式看起来并不太优雅...

0
by

评论人:gfredericks

需要考虑的因素

  • 统计数据仅是参数的函数,因此是否需要将整个属性包装起来?
    不过 Haskell 是这样做的。
  • 另一方面,我喜欢统计数据作为 {{check}} 命名空间的一般功能的特定实例的想法,但当前的实现并没有完全达到这个目标,因为我们在 {{check}} 命名空间中有大量的标签内容
  • 但是很难将其移除,因为如果 {{check}} 只是暴露了一个通用的折叠功能,那么直接访问 {{quick-check}} 的用户将需要提供两个东西——一个包装过的属性,以及正确折叠函数
0
by

评论者为:nberger

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

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

  • 移除了将要作为开启/关闭每个测试的统计信息打印方式的 * } var。默认的 reporter-fn 现在只有在结果映射中存在标签时才会打印统计信息。如果要不打印统计信息,只需使用不同 :reporter-fn,该 :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

我们提到,可能在 collect 中将 nil 作为不标记的标志来处理,但我觉得我不太喜欢这个想法。

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

`
(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的。我认为这不是最终版本(我希望找到一种方式,例如,不把标签材料污染进主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

这个补丁有什么阻碍吗?

...