请在2024年Clojure状态调查!中分享您的看法。

欢迎!请访问关于页面以获取更多关于此操作的信息。

0
test.check

Test.check 包含一个种子概念,该种子在测试属性时使用。这个种子可以由当前时间提供或生成。无论如何,单个种子用于生成所有测试用例。如果测试失败,尝试在相同输入上重新测试属性的唯一方法是使用相同的种子重新运行所有测试。如果在找到失败之前测试已经运行数小时,这将非常有禁。

我更希望能够检查失败的精确输入属性。朝这个方向迈出的一步是为每个试验有一个显式的不同种子(可能是从初始元种子生成的),并且当失败时,报告一个可以使用以运行测试一次的[种子大小]对。

然而,这种与缩小的交互很有趣,因为我也想重新运行失败的缩放值。因为缩放值从未由已知的[种子大小]显式生成,所以仅仅这些信息是不够的。我们可能报告[种子大小 shrink-path],其中第三个元素是遍历缩小树的索引列表。这样做最糟糕的部分可能是它可能相当长。

无论如何,我认为类似于这样的设置将比当前的设置更有用。我可能将为维护的一个分叉分支编写类似的代码,但如果我们可以确定一个特定设计,我将很高兴提出补丁。

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

在理论上,这确实可以再现,但我不知道有任何内置机制能使其变得容易。我最终是这样的

给定这个

`
(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点不容易解决,并且包含一个小元组对我来说更方便。

我已经为此编写了一个POC,并且它运行得相当好。我使用 {{:key}} 指代元组,所以这个词不与 {{:seed}} 冲突。我最终将测试调用为 {{(foo 0 :key [329489249329323 19 []])}},但我可能还会想出一个不需要传递虚拟第一个参数的新方法。

0

评论者:gfredericks

我认为这类问题随着 TCHECK-96 的出现变得更加重要,因为如果缩小停止得太早,那么能够再次在不受时间限制的情况下运行它将是很好的(不需要像重新运行具有相同种子的 {{quick-check}} 那样运行所有先前的通过测试)。

我对这个想法有一个中间的想法,它没有我分叉中使用任意长“key”的缺点:我们将RNG提升为一个真正的可序列化值,然后在 {{quick-check}} 中,我们跟踪每个试验使用的 {{[rng size]}} 对,在失败的情况下报告该对。然后我们有一个类似于 {{quick-check}} 的新函数,它接受一个属性和一个对,运行一个单独的试验(如果失败,则缩小)。

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