Gen[String] 可以产生其他值吗?

Can Gen[String] Produce Other Values?

给定:

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

运行 sbt test returns 所有测试都成功了。

鉴于上述代码,x: String,即类型 Gen[String]fooOrBarString 是否可能等于除 foobar?

在我的实际代码中,我发现 x: String 的值似乎与 org.scalacheck.Prop.forAllGen[String] 参数不同。

所以,这就是为什么我要问是否有可能,对于上面的例子,x: String 是否可以不等于 foobar.

当 ScalaCheck 发现一些数据伪造 属性 时,它将尝试 "shrink" 数据以找到更小的反例。不幸的是,在此过程中,某些 Gen 约束可能会丢失。这是一个known issue.

一种解决方法是使用 forAllNoShrink 而不是 forAll 来禁用收缩。

另一个解决方案是specify a postcondition on the generator with suchThat。例如参见 [​​=15=]

的定义
def oneOf[T](xs: Seq[T]): Gen[T] =
  choose(0, xs.size-1).map(xs(_)).suchThat(xs.contains)