Clojure 2024 年度调查 中分享您的想法!

欢迎!请参阅 关于 页面以了解更多关于如何使用本站的信息。

0 投票
test.check

包括支持添加嵌套属性的函数,这将是有益的。以下是这种工作方式的一个示例

`
(defn exists?
[e coll]
(some #{e} coll))

(defn remove-elem
[e coll]
(remove #{e} coll))

;; 这项测试应该失败,它说明了嵌套属性
(quick-check (for-all [v (gen/vector gen/int)]

           (for-all [e (elements v)]
             #(exists? e (remove-elem e v)))))

`

这项需求是支持实现属性具象化,但目前尚未实现。

这里 是原始问题 - GitHub #10

12 答案

0 投票

评论者:maciej.jaskowski

此问题的状态如何?
在以下情况下,若能启用此功能将对我们有很大帮助:我想验证我的路径查找算法在给定的图 G 中找到最优解,所以我生成了该图和大量的随机路径,并检查所有随机路径是否都“不如”算法找到的路径优。

有嵌套的 for-all 将会很简单。有没有其他方法可以做到这一点?

0 投票

评论者:reiddraper

抱歉这里更新的不及时。嵌套属性在我这边仍然处于初步阶段。好消息是它们只是方便而已,你可以通过使用 {{clojure.test.check.generators/bind}} 达到完全相同的效果。你可以看到如何使用 {{bind}} 的一个例子(链接:[https://github.com/clojure/test.check/blob/v0.5.8/doc/generator-examples.md#a-vector-and-a-random-element-from-it](https://github.com/clojure/test.check/blob/v0.5.8/doc/generator-examples.md#a-vector-and-a-random-element-from-it) 文件:这里)。

0 投票

评论者:maciej.jaskowski

显然我还需要一些提示,因为我只用 gen/bing 生成了成对的 '(graph list-of-random-paths)'

只要算法按预期运行,这就有用了。然而,一旦它失败了,就很难找出是哪个随机路径失败了。

0 投票

评论者:reiddraper

你可以展示你如何编写带有嵌套属性的测试吗?然后我或许可以帮助你将其改写为使用 {{bind}}。

0 投票

评论者:maciej.jaskowski

很好(图片:谢谢)

请看以下最重要的部分。

`
(defn gen-matrix-and-paths [size]

(gen/bind
  (gen-matrix gen/s-pos-int size)
  (fn [matrix]
    (let [ nodes (into [] (range (count matrix)))
           gen-perms (gen-permutations nodes)
           perms (distinct (gen/sample gen-perms 500)) ]
      (gen/tuple 
        (gen/return matrix) 
        (gen/return perms))))))

`

gen-matrix 生成一个平方关联矩阵,例如 (0 1) 或 (4 0) 的关联关系。
gen-permutations 生成提供的向量的排列。

0 投票

评论者:reiddraper

我有些困惑。你遇到了什么问题?你粘贴的代码使用了 {{bind}},而不是嵌套属性。

0 投票

评论者:maciej.jaskowski

好吧,但现在我只能写成这样:

`
(prop/for-all [data (gen-matrix-and-paths 6)]
(let [ [matrix random-paths] data ]

 (not-worse-then-others? tsp matrix random-paths))))

`

如果我的 'tsp' 算法不正确,将会指向一个矩阵以及一个路径向量的长度为500,其中之一将是反例。如果我能得到矩阵和单个反例会更好。

0 投票

评论者:reiddraper

我还不确定使用嵌套属性会是什么样子。你能请按照你想要的嵌套属性的方式编写代码吗?这将涉及至少两个全选项。

0 投票

评论者:maciej.jaskowski

当然可以!

我想这样写

`
(prop/for-all [matrix (gen-matrix 6)]
(prop/for-all [random-path (gen-random-path matrix)]

(<= (cost (tsp matrix)) (cost random-path))))

`

0 投票

评论者:maciej.jaskowski

ping!

0 投票

评论者:reiddraper

好的,让我们将其翻译成使用{{gen/bind}}。就像嵌套属性一样,{{bind}}允许你创建依赖于另一个生成器的生成器。例如,你的{{gen-random-path}}依赖于之前生成的{{matrix}}变量。因此,让我们编写一个返回{{matrix}}和{{random-path}}的生成器。

`
(def matrix-and-path
"返回一个[matrix random-path]的双元组"
(gen/bind (gen-matrix 6)

        (fn [matrix]
           (gen/tuple (gen/return matrix) (gen-random-path matrix)))))

(prop/for-all [[matrix random-path] matrix-and-path]
(<= (cost (tsp matrix)) (cost random-path))
`

0 投票
参考:https://clojure.atlassian.net/browse/TCHECK-7(由hypirion报告)
...