请分享您的想法至2024 Clojure 状态调查!

欢迎!请访问关于页面了解更多此网站的工作方式。

0
test.check

Haskell QuickCheck 允许-for-all 表达式嵌套。当生成的值之间存在依赖关系时,这非常有用。test.check 也应该允许这样做。

目前,嵌套的-for-all 始终成功,这在某种程度上是有害的。

我已经添加了一个补丁来实拟这项功能。

9个回答

0

评论者:reiddraper

感谢Michael。我感谢补丁,但在我们深入到代码细节之前,还有几个设计细节可以进行讨论。作为一个相关的独立问题,我一直想实现类似您的{{CheckResult}}类型,但作为一个具有更多字段的记录。这些字段将包含诸如找到的任何错误 plain-text 描述、统计信息(类似于 QuickCheck 的{{collect}}、{{classify}}等)。我还想编写一个协议,允许基本类型(如布尔型)转换为此记录。这将类似于 Haskell QuickCheck 的{{Testable}}类型类。虽然这是一个技术性问题,但我认为我们应该将其与可嵌套的 for-alls 解决,尤其是在嵌套的 for-alls 可以通过在生成器级别使用bind来模拟时。这合理吗?

0

评论者:sperber

当然。

我个人会开始这个补丁,并从那里开始工作,除非你想要做一些基本的不同的事情,而不仅仅是添加一些功能。

无论如何,我如何才能帮助它实现?

0

评论者:reiddraper

好问题,我会认真思考并尽快回复您。我也希望尽快实现这一点。

0
_评论由:reiddraper_提供

抱歉延迟回复,这是我在使用中的草稿


diff --git a/src/main/clojure/clojure/test/check/properties.clj b/src/main/clojure/clojure/test/check/properties.clj
index 99b5222..139ae9a 100644
--- a/src/main/clojure/clojure/test/check/properties.clj
+++ b/src/main/clojure/clojure/test/check/properties.clj
@@ -8,13 +8,47 @@
 ;   请勿从本软件中删除此通知或任何其他通知。
 
 (ns clojure.test.check.properties
+  (:import clojure.test.check.generators.Generator)
   (:require [clojure.test.check.generators :as gen]))
 
+(defrecord Result [result pass? message stamps])
+
+(defprotocol ToResult
+  (to-result [a]))
+
+(extend java.lang.Object
+  ToResult
+  {:to-result (fn [b]
+               وبةعدم التحقق من الاستثناءات المحتملة هنا
+              (->Result b (not (false? b)) nil nil))})
+
+(extend nil
+  ToResult
+  {:to-result (fn [b]
+               (->Result b false nil nil))})
+
+(extend java.lang.Boolean
+  ToResult
+  {:to-result (fn [b]
+               (->Result b b nil nil))})
+
+(extend Generator
+  ToResult
+  {:to-result identity})
+
+(extend Result
+  ToResult
+  {:to-result identity})
+
+(defn message
+  [m property]
+  (assoc property :message m))
+
 (defn- apply-gen
   [function]
   (fn [args]
-    (let [result (try (apply function args) (catch Throwable t t))]
-      {:result result
+    (let [result (to-result (try (apply function args) (catch Throwable t t)))]
+      {:result (:result result)
        :function function
        :args args})))
 
@@ -29,9 +63,18 @@
   (for-all* [gen/int gen/int] (fn [a b] (>= (+ a b) a)))
   "
   [args function]
-  (gen/fmap
-    (apply-gen function)
-    (apply gen/tuple args)))
+  (gen/bind
+    (apply gen/tuple args)
+    (fn [a]
+      (let [result ((apply-gen function) a)]
+        (cond (gen/generator? result) (gen/fmap (fn [r] (println "foo") (update-in r :args #(conj % a))) result)
+              ;;; 备注:在我离开这个代码前的一些快速注释,
+              ;; 这个 :else 是因为这个 we're wrapping the result
+              $$$ with a {:result ...} map. 应该有条件地做。
+              .; 我们可能还需要两种结果类型,一种返回给
+              之行,另一种将 'args' 添加到此。
+              :else (do (println "bar") (gen/return result)))))
+    ))
 
 (定义绑定变量
   [绑定]
0
by

评论者:sperber

看起来没问题。然而,很难看出为什么它会比你说的更快地让你达到目标,比我的补丁更快...

0
by

评论者:reiddraper

bq. 看起来没问题。然而,很难看出为什么它会比你说的更快地让你达到目标,比我的补丁更快...

公平合理。这部分是因为我写草稿更容易。我在支持嵌套生成器时尝试涵盖的主要事情是确保

  1. 我们也支持即将到来的收集和返回测试统计信息的能力,就像 Haskell QuickCheck 的 collect 一样
  2. 我们有一种合理的方式将失败的测试返回给用户。目前,在返回映射的 {{:fail}} 和 {{:smallest}} 键中,我们告诉用户失败的参数。由于您可能使用多个生成器,因此它们至少被包装在一个向量中。对于嵌套属性,我们怎么办?我们在“同级别”的多个生成器与嵌套属性之间如何区分?或者我们不需要区分?我们决定做的事情是否可以与向后兼容?

关键是,我想确保我们在获得一些这些答案之前不会对我们的嵌套属性做出承诺,对我来说,尝试一起玩这些事情的更容易,看看它们将如何组合。

0
by
_评论由:expez_发表的

我 really 不想必须嵌套 for-all,我更愿意它像 let 那样工作,这样我们就能引用前面的值。 不用说,无论哪种解决方案,这是我对 test.check 当前最大的不满,所以任何解决方案都胜过一年无所事事的时间。

这是一个解决方案,来自野外。我相信还有更多,人们真的很想要这个,但这是从 Nathan Marz 的 specter 库中取出的


(宏定义 for-all+ [绑定 & body]
  (let [parts (partition 2 bindings)
        vars (vec (map first parts))
        genned (reduce
                     (fn [curr [v code]]
                     `(gen/bind ~code (fn [~v] ~curr)))
                   `(gen/return ~vars)
                (reverse parts))]
    `(prop/for-all [~vars ~genned]
                   ~@body )))
0

评论者:gfredericks

我们正在考虑与(链接: http://dev.clojure.org/jira/browse/TCHECK-81 文本:TCHECK-81)类似的问题,同时还有一个更华丽的 {{for-all}}变体(链接: https://github.com/gfredericks/test.chuck#properties 文本:这里)。

0
参考: https://clojure.atlassian.net/browse/TCHECK-44(由 alex+import 报告)
...