0

Given:

import org.scalatest._
import org.scalatest.prop.Checkers
import org.scalacheck.Gen
import org.scalacheck.Gen._

object Test {
  def fooOrBar: Gen[String] = oneOf("foo", "bar")
}

class Test extends FunSuite with Checkers {

  import Test._

  test("generated String should equal 'foo' or 'bar'") {
    check( org.scalacheck.Prop.forAll(fooOrBar) { x: String =>
      x == "foo" || x == "bar"
    })
  }
}

Running sbt test returns that all tests have succeeded.

Given the above code, is it possible for x: String, i.e. the String of fooOrBar, of type Gen[String], to equal a value other than foo or bar?

In my real-world code, I'm seeing values for my x: String that appear to differ from the Gen[String] argument to org.scalacheck.Prop.forAll.

So, that's why I'm asking if it's possible, for the above example, whether x: String can not equal foo or bar.

Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • I needed to use `org.scalacheck.Prop.forAllNoShrink` – Kevin Meredith Jun 02 '16 at 19:11
  • Shrinking doesn't play well with generators indeed. Same thing if you have filtering conditions `suchThat`. – Eric Jun 03 '16 at 09:43
  • @Eric - care to post an answer for credit? I found that `forAllNoShrink` had worked for me, but I'm not entirely sure what "shrinking" involves. – Kevin Meredith Jun 13 '16 at 21:35
  • Done. I actually learned that `suchThat` was one way to fix this whereas I used to think that `suchThat` conditions were not maintained during shrinking. – Eric Jun 14 '16 at 06:08

1 Answers1

1

When ScalaCheck finds some data falsifying a property, it will then try to "shrink" the data to find a smaller counter-example. Unfortunately during this process some Gen constraints might be lost. This is a known issue.

One work-around is to disable shrinking by using forAllNoShrink instead of forAll.

Another solution is to specify a postcondition on the generator with suchThat. For example see the definition of Gen.oneOf

def oneOf[T](xs: Seq[T]): Gen[T] =
  choose(0, xs.size-1).map(xs(_)).suchThat(xs.contains)
Eric
  • 15,494
  • 38
  • 61