鉴于此:
property("Empty range") {
forAll { (min: Int, max: Int) =>
whenever (min == max) {
Range(min, max).size should be (0)
}
}
}
我得到了
[info] - Empty range *** FAILED ***
[info] Gave up after 5 successful property evaluations. 96 evaluations were discarded.
我如何表达我的测试用例,即捕获不管a
和b
的Range的属性,如果它们相等,那么Range(a,b)
应为空。< / p>
另一个:
property("10 long range") {
forAll { (min: Int, max: Int) =>
whenever (min < max && (max.toLong-min.toLong).abs == 10) {
Range(min, max).head should be (min)
}
}
}
我有一堆像这样的测试用例(类似于Range
的类),所有这些都失败并出现相同的错误。
我想捕获具有给定大小的Ranges,并测试该范围内的元素 - 我希望ScalaCheck为我生成范围边界。
答案 0 :(得分:1)
对于迟到的回复感到抱歉,但是,对于您的第一种情况,由于您只是测试两个匹配值的范围是0,您只需要生成一个值:
property("Empty range") {
forAll { x: Int =>
Range(x, x).size should be (0)
}
}
通过对此测试使用whenever
案例,生成两个相等值的概率非常低,因此您将浪费min
&amp;的许多组合。 max
不平等。最终,它会放弃尝试找到满足条件的组合。上面的替代方法适用于每个生成的值,因此它也更有效。
第二个例子是类似的。首先,将丢弃min
为&gt; = max
的所有情况。然后,将丢弃两个值之间的差异不是10的所有情况。因此,再一次,生成比min
值正好小10 max
值的机会非常低,以至于测试将放弃尝试查找满足此条件的值。同样,以下内容等同于您所拥有的内容,并且将对大多数生成的值起作用(只需要丢弃最大值10以内的值,以避免在添加时出现溢出)。
property("10 long range") {
forAll { x: Int =>
whenever (x <= Int.MaxValue - 10) {
Range(x, x + 10).head should be (min)
}
}
}
但是,您的测试似乎有点不寻常,因为您正在测试一些非常具体的情况,而您应该寻找更一般的条件。例如:
property("Range size") {
forAll { (min: Int, max: Int) =>
whenever (min <= max && (max.toLong - min.toLong) <= Int.MaxValue) {
Range(min, max).size should be (max - min)
}
}
}
应涵盖所有大小比较,包括两个值相等且大小为0的情况。(在这种情况下,whenever
子句是必需的,以防止min
值高于max
值并确保范围大小不超过Int
的容量。您也可以编写此测试,在生成的数字方面稍微更有效,如下所示:
property("Range size #2") {
forAll { (a: Int, b: Int) =>
whenever (Math.abs(a.toLong - b.toLong) <= Int.MaxValue) {
val min = Math.min(a, b)
val max = Math.max(a, b)
Range(min, max).size should be (max - min)
}
}
}
在上述两种情况下,whenever
条款偶尔会失败 - 特别是在后一种情况下 - 而不是几乎所有时间。