分享您的想法,参加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

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

我认为它回答了测试.check设计页面上的问题“我们如何收集关于生成的事物类型的统计数据?”

13 答案

0

评论者:nberger

这些补丁在引入reporter-fn后不再适用。

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

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

0

评论者:gfredericks

需要考虑的事项

  • 统计数据仅是参数的函数,因此是否需要包装整个属性?
    不过 Haskell 确实这样做了
  • 另一方面,我喜欢将统计数据视为 {{check}} 命名空间的通用功能的一个具体实例,但目前的实现并没有达到这个程度,因为我们在 {{check}} 命名空间中有很多标签内容
  • 但将其移出去很难,因为如果 {{check}} 只是暴露了一个通用化简特征,那么直接前往 {{quick-check}} 的用户将必须提供两件事——一个包装过的属性,以及合适的化简函数
0

评论者:nberger

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

在这个新补丁中,有些东西被简化了

  • 移除了新的 * } 变量,该变量本来可以用作在每个测试中启用/禁用打印统计数据的方法。现在默认的 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)}}: 这是当前的签名。只有当 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版本对应。

我们讨论了可能在{{collect}}中将{{nil}}作为不标记的标志处理,但我觉得这个主意不太好。

0

评论者:gfredericks

我应该也不会忘记,这可能和其他对解决“测试失败反馈”问题进行更改相关联:[a rel="nofollow" href="http://dev.clojure.org/display/design/test.check" target="_blank">http://dev.clojure.org/display/design/test.check

0

评论者:gfredericks

我应该也不会忘记,这可能和其他对解决“测试失败反馈”问题进行更改相关联:[a rel="nofollow" href="http://dev.clojure.org/display/design/test.check" target="_blank">http://dev.clojure.org/display/design/test.check

0

评论者:nberger

bq. 我们讨论了可能在{{collect}}中将nil作为不标记的标志处理,但我觉得这个主意不太好。

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

评论者:nberger

添加了一个新补丁 TCHECK87-add-stats-feature-2.patch,它基于当前的 master 分支。我认为这不是最终版本(我希望找到一种方法,例如,不将标签内容污染主快速检查循环)但它有望更加接近。

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

有什么东西阻止这个补丁吗?

...