2024 Clojure调查问卷中分享您的想法!

欢迎!请查看关于页面以获取更多关于该功能的信息。

0 投票
test.check

受Haskell的QuickCheck中的类似功能启发。添加了一个{{classify}}函数,该函数旨在作为{{prop/for-all}}的包装器使用,返回一个适当的属性(生成器),可以增强底层属性返回的结果-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报告中,以便进行统计计算。

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

0 投票

评论人:gfredericks

需要考虑的事项

  • 统计信息仅是参数的函数,那么是否需要将整个属性包装起来?
    然而,Haskell语言却是这样做的
  • 另一方面,我喜欢将统计信息视为{{check}}命名空间中通用功能的一个特定实例的想法,但由于我们在{{check}}命名空间中有大量的标签内容,当前实现并没有完全达到这个目的
  • 但是移动它很有难度,因为如果{{check}}只是暴露了一个通用的reduce功能,那么直接访问{{quick-check}}的用户将必须提供两项内容——包装后的属性和适当的reduce函数
0 投票
by

评论者:nberger

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

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

  • 移除了将要用来启用/禁用每个测试统计信息打印的新的* } var。默认-reporter-fn现在只有在结果映射中存在标签时才打印统计信息。若要打印统计信息,只需要使用一个不打印统计信息的不同:reporter-fn即可。
  • 在统计信息报告中,现在只打印带有标签的行。在先前版本中,有一个“无标签”试验百分比的行。我现在已经移除了它,以减少冗余。

还增加了docstrings,确保统计信息在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页面上“测试失败反馈”问题所做的变更重叠: http://dev.clojure.org/display/design/test.check

0 投票

评论人:gfredericks

我还不应该忘记这一点可能与其他对confluence页面上“测试失败反馈”问题所做的变更重叠: http://dev.clojure.org/display/design/test.check

0 投票

评论者:nberger

bq. 我们讨论过可能将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 投票

评论者:nberger

替换了新的补丁,添加了{{stats/classify}}和{{stats/collect}},正如之前讨论的那样。我认为这个新补丁实现了讨论的内容,包含2和5的情况,函数命名与haskell实现相似,没有对nil进行特殊的处理(它是一个有效的标签),也没有添加我之前评论中提到的{{:stats/ignore}}。

0 投票

评论者:nberger

添加了一个新的补丁TCHECK87-add-stats-feature-2.patch,它基于当前主分支更新。我认为这还不是最终版本(例如,我想找到一种方法,不要让标签之类的东西污染主quickcheck循环),但是它正在逐步接近。

0 投票

评论者:nberger

添加了一个基于当前主分支的新补丁TCHECK87-add-stats-feature-3.patch,其中包含一些合并的提交。同时解决了ClojureScript中的print-stats测试问题。

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

这个补丁有什么问题阻止了它?

...