请在 2024 Clojure 调查问卷! 中分享您的想法。

欢迎!请参阅 关于 页面,了解有关此工作方式的更多信息。

+2
Spec
重新标记

(s/gen ratio?) 被实现为 (gen/such-that ratio? gen/ratio)

问题是,大约有 10% 的时间 gen/ratio 返回一个整数,这使得 ratio? 前缀失败。如果连续发生 10 次,则 gen/such-that 会抛出异常。

在有足够大的样本量的情况下,(s/gen ratio?) 可靠地失败

(dorun (gen/sample (s/gen ratio?) 10000000))

Execution error (ExceptionInfo) at clojure.test.check.generators/fn (generators.cljc:435).
Couldn't satisfy such-that predicate after 10 tries.

一个快速的解决办法是增加 such-thatmax-tries 参数

(dorun (gen/sample (gen/such-that ratio? gen/ratio 100) 10000000))

=> nil

然而,我也觉得奇怪的是,`(s/gen ratio?)` 总是生成 `Ratio`,而 `gen/ratio` 生成的是比例和整数的混合。因此,可能更好的修复方法是更新 `gen/ratio` 以不生成整数?

2 个答案

0

是的,看来有些奇怪,gen/ratio 有时会生成整数——这来自 test.check。但只接受比例且不接受整数的规范似乎也不寻常——这对于您的用例真的有意义吗?

我们没有接受比率而没有整数的规范,而是我们有接受大多数如果并非所有数字类型的规范,并需要能生成所有这些不同类型(包括比率)以正确测试它们。

不幸的是,内置的生成器 `(s/gen number?)` 仅生成长整数和双精度浮点数(这是一个完全不同的主题),因此我们有意在我们的测试中生成大整数,大十进制数,比率等。我生成比率的方法是使用 `(s/gen ratio?)`,这导致测试因异常产生的不稳定性(如果你曾经遇到过这种不稳定性,你会知道它们是最难调试的!但这也是一个单独的主题)。

切换到 `(gen/ratio)` 解决了这个问题,并且适用于我的用例,因为我们的规范也恰好接受整数,但我花了相当多的时间才到达这个阶段。
0
...