Scala中的ForAll检查会跳过一些输入,并且不考虑容器大小

时间:2019-03-30 17:44:21

标签: scala scalatest scalacheck

我是scala检查的新手,我想测试我的应用程序的以下部分。我想生成30和20个随机事件,并检查我的应用程序代码是否正确计算了结果

// generate 30 random events
val eventGenerator: Gen[Event] = for {
  d <- Gen.oneOf[String](Seq("es1", "es2", "es3"))
  t <- Gen.choose[Long](minEvent.getTime, maxEvent.getTime)
  s <- Gen.oneOf[String](Seq("s1", "s2", "s3", "s4", "s5", "s6", "s7"))} yield Event(d, t, s)
val eventsGenerator: Gen[List[VpSearchLog]] = Gen.containerOfN[List, VpSearchLog](30, eventGenerator)

// generate 20 random instances
val instanceGenerator: Gen[Instance] = for {
  d <- Gen.oneOf[String](Seq("es1", "es2", "es3"))
  t <- Gen.choose[Long](minInstance.getTime, maxInstance.getTime)} yield Instance(d, new Timestamp(t))
val instancesGenerator: Gen[List[Instance]] = Gen.containerOfN[List, Instance](20, instanceGenerator)

val p: Prop = forAll(instancesGenerator, eventsGenerator) { (i, e) =>

  println(i.size)
  println(e.size)
  println()
  val instancesWithFeature = computeExpected(instance)

  isEqual(transform(instance), instanceWithFeature)
}

出于某种原因,我在标准输出中看到了这一点

  20
  15

  20
  7

  20
  3

  20
  1

  20
  0
  starting to compute expected:

基本上,forAll会生成几个具有一定大小的输入,然后跳过它们。对于某些原因,当输入之一的大小为0时,它将开始计算事物,然后开始进行适当的检查。我的问题是:

  • 为什么如果我使用containerofNlistOfN我没有得到确切的特定尺寸的输入?然后如何生成这样的输入?
  • forAll开始探索可能的输入的空间并跳过其中一些是正常的吗?我在这里想念什么吗?对于我来说,这种行为很不直观

1 个答案:

答案 0 :(得分:1)

您可能需要使用forAllNoShrink来避免ScalaCheck中shrinking fails to respect generators处的已知缺陷

val thirtyInts: Gen[List[Int]] =
  Gen.listOfN[Int](30, Gen.const(99))

val twentyLongs: Gen[List[Long]] =
  Gen.listOfN[Long](20, Gen.const(44L))

property("listOfN") = {
  Prop.forAllNoShrink(thirtyInts, twentyLongs) { (ii, ll) =>
    ii.size == 30 && ll.size == 20
  }
}