3
votes

I have a nested forAll call which depends on the value generated by the previous one. This value is a collection that should not be empty according to its generator's definition:

"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)
    }
  }
}

Instead of producing an error message such as "true was not false", this gives me:

IllegalArgumentException was thrown during property evaluation.
  Message: oneOf called on empty collection
  Occurred when passed generated values (
    arg0 = List() // 2 shrinks
)

and I cannot figure out why. This is not what I would expect (or understand) as a test failure message...

If I print out the generated lists and ints, I get the following strange output:

List(72, 77, 8)
8
4
2
1
0
List(72)
72
36
18
9
4
2
1
0
List()

The integers are divided by two upon property failure as the list is truncated (but according to the generator definition, the list should always be of size 3!)

I'm using Scala 2.12.1, scalatest 3.0.1 abd scalacheck 1.13.4 .

Thanks!

1

1 Answers

1
votes

Turns out this mechanism is called "shrinking" and can be disabled by adding these implicits into scope:

  def noShrink[T] = Shrink[T](_ => Stream.empty)
  implicit val intListNoShrink = noShrink[List[Int]]
  implicit val intNoShrink = noShrink[Int]

This link helped a lot: https://github.com/scalatest/scalatest/issues/584