【发布时间】:2018-11-27 00:25:48
【问题描述】:
在 ScalaCheck 中,我有一个使用正整数生成器的属性测试,当它失败时,ScalaCheck 将缩小为非正值。
收缩应该有助于找到最小的失败案例。缩小到所需范围之外的值是令人困惑且无益的。这是一个已知的错误,请参阅ScalaCheck issue #129 Gen.suchThat not respected by shrinking
是否可以在范围内定义我自己的收缩实例,使其仅收缩为正整数?
示例
这是一个最小的属性测试:
class ShrinkProp extends Properties("Shrink") {
property("posNum[Int]") = {
Prop.forAll(Gen.posNum[Int]) { _: Int =>
Prop.falsified
}
}
}
这通常会导致 ScalaCheck 将参数缩小到零:
[信息] 完成编译。 [信息]! Shrink.posNum[Int]:0 次通过测试后伪造。 [信息] > ARG_0: 0 [信息] > ARG_0_ORIGINAL:1 [信息] 失败:总计 1,失败 1,错误 0,通过 0或者更糟的是,它有时会缩小到负值:
[信息]! Shrink.posNum[Int]:5 次通过测试后伪造。 [信息] > ARG_0:-1 [信息] > ARG_0_ORIGINAL:3 [信息] 失败:总计 1,失败 1,错误 0,通过 0禁用收缩
一种解决方案是使用forAllNoShrink 关闭收缩:
class ShrinkProp extends Properties("Shrink") {
property("posNum[Int]") = {
Prop.forAllNoShrink(Gen.posNum[Int]) { _: Int =>
Prop.falsified
}
}
}
结果没有缩水:
[信息]! Shrink.posNum[Int]:0 次通过测试后伪造。 [信息] > ARG_0: 1 [信息] 失败:总计 1,失败 1,错误 0,通过 0添加警卫
另一种选择是在测试中添加一个守卫,以便他缩小值或只是跳过:
import Prop.BooleanOperators
class ShrinkProp extends Properties("Shrink") {
property("posNum[Int]") = {
Prop.forAll(Gen.posNum[Int]) { x: Int =>
(x >= 1) ==> Prop.falsified
}
}
}
除了禁用收缩和添加保护之外,还有其他方法吗?
【问题讨论】:
标签: scala scalacheck