Scalacheck嵌套forall抛出;在空集合中调用其中一个“;关于Scalatest测试中的失败

Scalacheck嵌套forall抛出;在空集合中调用其中一个“;关于Scalatest测试中的失败,scala,scalatest,scalacheck,Scala,Scalatest,Scalacheck,我有一个嵌套的forAll调用,它取决于前一个调用生成的值。根据生成器的定义,此值是不应为空的集合: "test" in { val listGen: Gen[List[Int]] = Gen.listOfN(3, Gen.choose(0, 100)) def intGen(list: List[Int]) = Gen.oneOf(list) implicit val arbList = Arbitrary(listGen) forAll { list: List[Int]

我有一个嵌套的forAll调用,它取决于前一个调用生成的值。根据生成器的定义,此值是不应为空的集合:

"test" in {
  val listGen: Gen[List[Int]] = Gen.listOfN(3, Gen.choose(0, 100))
  def intGen(list: List[Int]) = Gen.oneOf(list)
  implicit val arbList = Arbitrary(listGen)

  forAll { list: List[Int] =>
    forAll(intGen(list)) { int =>
      true should be(false)
    }
  }
}
这不是生成错误消息,如“true was not false”,而是提供:

IllegalArgumentException was thrown during property evaluation.
  Message: oneOf called on empty collection
  Occurred when passed generated values (
    arg0 = List() // 2 shrinks
)
我不知道为什么。这不是我期望(或理解)的测试失败消息

如果我打印出生成的列表和整数,我会得到以下奇怪的输出:

List(72, 77, 8)
8
4
2
1
0
List(72)
72
36
18
9
4
2
1
0
List()
当列表被截断时,当属性失败时,整数被除以2(但根据生成器定义,列表的大小应始终为3!)

我使用的是Scala 2.12.1、scalatest 3.0.1和scalacheck 1.13.4


谢谢

结果表明,这种机制被称为“收缩”,可以通过在作用域中添加以下隐式来禁用:

  def noShrink[T] = Shrink[T](_ => Stream.empty)
  implicit val intListNoShrink = noShrink[List[Int]]
  implicit val intNoShrink = noShrink[Int]
这个链接帮助很大: