请在 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

然而,我也觉得 odd,为什么 (s/gen ratio?) 总是生成 Ratio,而 gen/ratio 生成的是一个比率与整数的混合体。因此,可能更好的解决方法是更新 gen/ratio 以不生成整数?

2 个回答

0

是的,看起来很奇怪,有时候 gen/ratio 生成整数 - 来源于 test.check。但是,对于只接受比率但不接受整数的规范似乎也很奇怪 - 这对您的用例有实际意义吗?

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

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

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