2024 Clojure 状态调查!中分享您的想法。

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

0
test.check

test.check 概念包括用于测试属性的种子。这个种子可以是当前时间提供的,也可以是生成的。无论如何,单个种子用于生成测试的所有试验。如果测试失败,再次在相同输入上尝试重新测试属性的唯一方法是在相同的种子下运行所有测试。如果测试在发现失败之前运行了几个小时,这将是一个障碍。

我更希望能够检查失败的 exactly 输入。这一步骤中有一项是给每个试验一个明确的不同的种子(可能从一个初始元种子生成),在失败时报告一个 {{[种子大小]}} 对,以便一次性运行测试。

但是这与缩小的方式也有所互动,因为我也可能想要运行失败的缩小值。由于缩小值从未明确地从已知 {{[种子大小]}} 生成,所以仅仅这个信息是不够的。我们可能会报告 {{[种子大小缩小路径]}},其中第三项是遍历缩小树索引列表。可能最糟糕的部分是,这可能会相当长。

无论如何,我认为这类东西比当前的设置更有用。我可能正在为一个我维护的分支胡乱拼凑一些类似的东西,但如果我们可以确定一个具体的设计,我将很高兴提供一个补丁。

4 答案

0
_评论者:reiddraper_

当测试失败时,我们确实会返回最初失败的解释和缩小测试的参数。这还不够吗?

例如

{code:none}
      {:result false,
       :failing-size 45,
       :num-tests 46,
       :fail [[10 1 28 40 11 -33 42 -42 39 -13 13 -44 -36 11 27 -42 4 21 -39]],
       :shrunk {:total-nodes-visited 38,
               :depth 18,
               :result false,-------------
                :smallest [[42]]}}


参见 {{:fail}} 和 {{[:shrunk :smallest]}}。
0

评论由:gfredericks 发布

在理论上 Certainly 足以复制,但我不知道任何内置机制这使得它容易。以下是我最终做的事情

给定这个

`
(defspec foo
(prop/for-all [x gen]

(f x)))

`

在得到一个包含 50 行缩小值失败后(例如 {{:bar}}),我手动打印它并将其粘贴回我的文件中,如下所示

`
(def shrank
':bar)

(defspec foo
(prop/for-all [x #_gen (gen/return shrank)]

(f x)))

`

现在我可以运行 {{(foo 1)}} 来重新运行带有失败值的测试。

这种尴尬的局面部分是由于三个事实造成的

  1. 我的生成器产生庞大的难以控制的价值
  2. 我的属性是一大堆代码而不是一个单一功能
  3. 没有简单的方式来测试特定值上的属性

我可以通过修正 2 来减少一些痛苦,使每个测试分为 {{defspec}} / {{prop/for-all}} 和一个普通的函数。但是 1 很难解决,而一个小元组对我来说更为宜人。

我已经为这个写了一个原型,它效果相当不错。我用 {{:key}} 这个词来指代元组,所以这个词不会与 {{:seed}} 冲突。我最终调用测试就像 {{(foo 0 :key [329489249329323 19 []])}},但我可能会想出其他不需要传递虚拟第一个参数的方法。

0

评论由:gfredericks 发布

我认为这种问题的重要性在 TCHECK-96 中变得更加重要,因为如果缩小值提前终止,那么能够在没有时间限制的情况下再次运行它将非常棒(不必像重新运行 {{quick-check}} 同样的种子那样运行所有先前的通过测试)。

我刚刚为此想出了一个不含有我在分叉中使用的任意长“键”的缺点的新想法:我们将 RNG 提升为真正的可序列化值,然后我们在 {{quick-check}} 中跟踪每个试验使用的 {{[rng size]}} 对,在失败时报告那个对。然后我们有一个类似于 {{quick-check}} 的新函数,它接受一个属性和一个对并运行一个试验(如果失败则缩小)。

0
参考:https://clojure.atlassian.net/browse/TCHECK-21 (由 gfredericks 报告)
...