请在 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。但这似乎也有些奇怪,有一个只接受比率但不接受整数的 spec——这对您的用例来说真的有意义吗?

我们没有接受比值和非整数的规范,而是大多数情况下接受所有数字类型的规范,并且需要能够生成所有这些不同类型(包括比值)来正确测试它们。

不幸的是,内置的生成器((s/gen number?))仅生成长整型和双精度浮点数(这是一个完全独立的话题),因此我们在测试中故意生成大整数、大浮点数、比值等。我生成比值的方式是((s/gen ratio?)),这导致了由such-that异常引起的测试正常运行不正常(如果你曾经遇到过这样的非正常运行,你会知道这是最难调试的!但这也同样是一个独立的话题)。

切换到((gen/ratio))解决了这个问题,并且在我的用例中它也起作用,因为我们的规范也恰好接受整数,但我花费了相当多的时间去达到这一点。
0
...