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。但也感觉很奇怪,有一个只接受分数而不接受整数的规范——这真的适合您的用例吗?

by
我们没有只接受分数不接受整数的规范,而是我们有接受大部分(如果不是所有)数字类型的规范,并且需要能够生成所有这些不同的类型(包括分数)来正确测试它们。

不幸的是,内置的生成器 `(s/gen number?)` 只生成长和双精度浮点数(这又是一个完全不同的主题),所以我们故意在我们的测试中生成了大整数、大浮点数、分数等。我生成分数的方式是使用 `(s/gen ratio?)`,这由于那种-what异常(如果您曾经经历过这样的碎片,您会知道它们是最难调试的!但那也是一个独立的话题)而导致测试失败。

切换到 `(gen/ratio)` 解决了这个问题,并且对我的用例也有效,因为我们的规范也恰好接受整数,但我为此花了很多时间。
0
by
...