ScalaCheck:Gen.choose 输出超出指定范围的值
ScalaCheck: Gen.choose outputting values beyond a specified range
作为作业的一部分,我正在使用 Scalacheck 查找缺陷。也许令人难以置信的是,我被困住了,因为它正在生成一对非零整数。
来自我的 IntelliJ 工作表,逐字记录:
import org.scalacheck._
import Arbitrary._
import Gen._
import Prop._
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(i+1,1000)
if (i < j)
} yield (i,j)
val kk = forAll (genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x == y
}
kk.check
因为,我明确提到所选值的最小值不为零,所以我不应该在 属性 中看到任何零,对吧?至少,这是我的理解。但这是我看到的:
x =134, y =547
x =0, y =547
x =0, y =0
x =0, y =274
x =0, y =0
x =0, y =137
x =0, y =0
x =0, y =69
x =0, y =0
x =0, y =35
x =0, y =0
x =0, y =18
x =0, y =0
x =0, y =9
x =0, y =0
x =0, y =5
x =0, y =0
x =0, y =3
x =0, y =0
x =0, y =2
x =0, y =0
x =0, y =1
x =0, y =0
! Falsified after 0 passed tests.
> ARG_0: (0,1)
> ARG_0_ORIGINAL: (134,547)
res0: Unit = ()
这些零来自哪里?我缺少什么?也许,有些明显的东西,但我的眼睛没有捕捉到它们。
我正在使用 Scalcheck 版本 1.12.1
Seq("org.scalacheck" %% "scalacheck" % "1.12.1")
任何帮助,不胜感激。
更新 I:按照@samar 的建议(我也在 gitbook 中找到了相同的参考),我尝试用 suchThat 过滤生成器。但运气不佳(代码如下):
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000).suchThat(_ > 0)
j <- Gen.choose(i+1,1000).suchThat(_ > 0)
if (i < j)
} yield (i,j)
val kk = forAll (genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x == y
}
kk.check
我运行这段代码大概重复了6-7次。这是一个 运行dom 输出。
x =536, y =730
x =0, y =730
x =0, y =0
x =0, y =365
x =0, y =0
x =0, y =183
x =0, y =0
x =0, y =92
x =0, y =0
x =0, y =46
x =0, y =0
x =0, y =23
x =0, y =0
x =0, y =12
x =0, y =0
x =0, y =6
x =0, y =0
x =0, y =3
x =0, y =0
x =0, y =2
x =0, y =0
x =0, y =1
x =0, y =0
! Falsified after 0 passed tests.
> ARG_0: (0,1)
> ARG_0_ORIGINAL: (536,730)
res0: Unit = ()
更新二:为了确认,我听从了埃里克的建议并做了这个:
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(i+1,1000)
if (i != 0 && j != 0)
} yield {
(i,j)
}
val kk = forAllNoShrink(genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x < y
}
kk.check
这个有效:
x =805, y =1000
x =742, y =926
x =772, y =919
x =219, y =686
x =999, y =1000
x =752, y =792
x =163, y =585
x =721, y =735
x =251, y =866
x =383, y =887
x =797, y =939
x =925, y =947
x =291, y =951
x =502, y =619
x =422, y =756
x =159, y =886
x =49, y =955
x =624, y =819
x =922, y =979
x =881, y =894
x =936, y =952
x =908, y =975
x =802, y =976
x =918, y =946
x =564, y =823
x =544, y =751
x =916, y =938
x =57, y =762
x =614, y =963
x =497, y =986
x =102, y =332
x =264, y =643
x =611, y =720
x =542, y =797
x =704, y =784
Output exceeds cutoff limit.
更新三:
FWIW,我发现通过移动到 Scalacheck 版本 1.13.1(最初是 1.12.x),我得到以下行为:
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(1,1000)
if (i < j)
} yield {
(i,j)
}
val kk = forAll(genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x < y
}
kk.check
产生
x =56, y =752
x =395, y =532
x =468, y =828
x =326, y =749
x =203, y =973
x =294, y =393
x =589, y =975
x =44, y =75
x =406, y =533
x =33, y =381
x =405, y =767
x =13, y =883
x =201, y =341
x =593, y =991
x =636, y =913
x =508, y =782
x =333, y =861
x =306, y =863
x =428, y =537
x =373, y =775
x =74, y =462
x =196, y =299
x =245, y =535
x =312, y =993
x =940, y =989
x =12, y =708
但是通过将条件从小于更改为相等,会发生这种情况:
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(1,1000)
if (i < j)
} yield {
(i,j)
}
val kk = forAll(genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x == y
}
kk.check
产生
x =370, y =585
x =0, y =585
x =0, y =0
x =0, y =293
x =0, y =0
x =0, y =147
x =0, y =0
x =0, y =74
x =0, y =0
x =0, y =37
x =0, y =0
x =0, y =19
x =0, y =0
x =0, y =10
x =0, y =0
x =0, y =5
x =0, y =0
x =0, y =3
显然,应用的条件 覆盖了 我留给生成器的明确说明。这不是有点不直观吗?别人怎么看?
应该是属性缩水的原因吧。请尝试使用 forAllNoShrink
。
作为作业的一部分,我正在使用 Scalacheck 查找缺陷。也许令人难以置信的是,我被困住了,因为它正在生成一对非零整数。
来自我的 IntelliJ 工作表,逐字记录:
import org.scalacheck._
import Arbitrary._
import Gen._
import Prop._
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(i+1,1000)
if (i < j)
} yield (i,j)
val kk = forAll (genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x == y
}
kk.check
因为,我明确提到所选值的最小值不为零,所以我不应该在 属性 中看到任何零,对吧?至少,这是我的理解。但这是我看到的:
x =134, y =547
x =0, y =547
x =0, y =0
x =0, y =274
x =0, y =0
x =0, y =137
x =0, y =0
x =0, y =69
x =0, y =0
x =0, y =35
x =0, y =0
x =0, y =18
x =0, y =0
x =0, y =9
x =0, y =0
x =0, y =5
x =0, y =0
x =0, y =3
x =0, y =0
x =0, y =2
x =0, y =0
x =0, y =1
x =0, y =0
! Falsified after 0 passed tests.
> ARG_0: (0,1)
> ARG_0_ORIGINAL: (134,547)
res0: Unit = ()
这些零来自哪里?我缺少什么?也许,有些明显的东西,但我的眼睛没有捕捉到它们。
我正在使用 Scalcheck 版本 1.12.1
Seq("org.scalacheck" %% "scalacheck" % "1.12.1")
任何帮助,不胜感激。
更新 I:按照@samar 的建议(我也在 gitbook 中找到了相同的参考),我尝试用 suchThat 过滤生成器。但运气不佳(代码如下):
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000).suchThat(_ > 0)
j <- Gen.choose(i+1,1000).suchThat(_ > 0)
if (i < j)
} yield (i,j)
val kk = forAll (genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x == y
}
kk.check
我运行这段代码大概重复了6-7次。这是一个 运行dom 输出。
x =536, y =730
x =0, y =730
x =0, y =0
x =0, y =365
x =0, y =0
x =0, y =183
x =0, y =0
x =0, y =92
x =0, y =0
x =0, y =46
x =0, y =0
x =0, y =23
x =0, y =0
x =0, y =12
x =0, y =0
x =0, y =6
x =0, y =0
x =0, y =3
x =0, y =0
x =0, y =2
x =0, y =0
x =0, y =1
x =0, y =0
! Falsified after 0 passed tests.
> ARG_0: (0,1)
> ARG_0_ORIGINAL: (536,730)
res0: Unit = ()
更新二:为了确认,我听从了埃里克的建议并做了这个:
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(i+1,1000)
if (i != 0 && j != 0)
} yield {
(i,j)
}
val kk = forAllNoShrink(genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x < y
}
kk.check
这个有效:
x =805, y =1000
x =742, y =926
x =772, y =919
x =219, y =686
x =999, y =1000
x =752, y =792
x =163, y =585
x =721, y =735
x =251, y =866
x =383, y =887
x =797, y =939
x =925, y =947
x =291, y =951
x =502, y =619
x =422, y =756
x =159, y =886
x =49, y =955
x =624, y =819
x =922, y =979
x =881, y =894
x =936, y =952
x =908, y =975
x =802, y =976
x =918, y =946
x =564, y =823
x =544, y =751
x =916, y =938
x =57, y =762
x =614, y =963
x =497, y =986
x =102, y =332
x =264, y =643
x =611, y =720
x =542, y =797
x =704, y =784
Output exceeds cutoff limit.
更新三: FWIW,我发现通过移动到 Scalacheck 版本 1.13.1(最初是 1.12.x),我得到以下行为:
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(1,1000)
if (i < j)
} yield {
(i,j)
}
val kk = forAll(genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x < y
}
kk.check
产生
x =56, y =752
x =395, y =532
x =468, y =828
x =326, y =749
x =203, y =973
x =294, y =393
x =589, y =975
x =44, y =75
x =406, y =533
x =33, y =381
x =405, y =767
x =13, y =883
x =201, y =341
x =593, y =991
x =636, y =913
x =508, y =782
x =333, y =861
x =306, y =863
x =428, y =537
x =373, y =775
x =74, y =462
x =196, y =299
x =245, y =535
x =312, y =993
x =940, y =989
x =12, y =708
但是通过将条件从小于更改为相等,会发生这种情况:
implicit lazy val genUnequalIntPairs = for {
i <- Gen.choose(1,1000)
j <- Gen.choose(1,1000)
if (i < j)
} yield {
(i,j)
}
val kk = forAll(genUnequalIntPairs) {
case (x,y) => println("x =" + x + ", y =" + y)
x == y
}
kk.check
产生
x =370, y =585
x =0, y =585
x =0, y =0
x =0, y =293
x =0, y =0
x =0, y =147
x =0, y =0
x =0, y =74
x =0, y =0
x =0, y =37
x =0, y =0
x =0, y =19
x =0, y =0
x =0, y =10
x =0, y =0
x =0, y =5
x =0, y =0
x =0, y =3
显然,应用的条件 覆盖了 我留给生成器的明确说明。这不是有点不直观吗?别人怎么看?
应该是属性缩水的原因吧。请尝试使用 forAllNoShrink
。