【问题标题】:Sized generators in scalacheckscalacheck 中的大小生成器
【发布时间】:2010-09-08 10:26:00
【问题描述】:

UserGuide 的 scalacheck 项目提到了大小的生成器。解释代码

def matrix[T](g:Gen[T]):Gen[Seq[Seq[T]]] = Gen.sized {size =>
 val side = scala.Math.sqrt(size).asInstanceOf[Int] //little change to prevent compile-time exception
 Gen.vectorOf(side, Gen.vectorOf(side, g))
}

对我没有任何解释。经过一番探索,我了解到生成序列的长度不取决于生成器的实际大小(根据 javadoc,Gen 对象中有 resize 方法“创建生成器的调整大小版本”(也许这意味着不同的东西?))。

val g =  Gen.choose(1,5)
val g2 = Gen.resize(15, g)
println(matrix(g).sample) //  (1)
println(matrix(g2).sample) // (2)
//1,2 produce Seq with same length 

您能否解释一下我遗漏了什么,并举例说明您如何在测试代码中使用它们?

【问题讨论】:

    标签: scala scalacheck


    【解决方案1】:

    vectorOf(现在被 listOf 替换)生成列表,其大小(线性)取决于 ScalaCheck 在评估生成器时设置的大小参数。当 ScalaCheck 测试一个属性时,它会为每个测试增加这个大小参数,导致测试的属性列表越来越大(如果使用了listOf)。

    如果您仅通过以嵌套方式使用listOf 生成器来创建矩阵生成器,您将获得大小取决于大小参数平方的矩阵。因此,当在属性中使用这样的生成器时,您最终可能会得到非常大的矩阵,因为 ScalaCheck 会增加每次测试运行的大小参数。但是,如果您按照 ScalaCheck 用户指南中的方式使用 resize 生成器组合器,您的最终矩阵大小将线性地取决于大小参数,从而在测试属性时获得更好的性能。

    您真的不必经常使用resize 生成器组合器。如果您需要生成受某个特定大小限制的列表,最好执行下面的示例,因为不能保证 listOf/ containerOf 生成器确实按照您期望的方式使用大小参数.

    def genBoundedList(maxSize: Int, g: Gen[T]): Gen[List[T]] = {
      Gen.choose(0, maxSize) flatMap { sz => Gen.listOfN(sz, g) }
    }
    

    【讨论】:

    • 这让我找到了Gen.frequency((10, 2), (5, 3), (1, 1)).flatMap(Gen.listOfN(_, names)),这正是我所需要的!
    【解决方案2】:

    您使用的vectorOf 方法已弃用,您应该使用listOf 方法。这会生成一个随机长度列表,其中最大长度受生成器大小的限制。因此,您应该调整生成器的大小 如果您想控制生成的最大元素,实际上会生成实际列表:

    
    scala> val g1 = Gen.choose(1,5)
    g1: org.scalacheck.Gen[Int] = Gen()
    
    scala> val g2 = Gen.listOf(g1)  
    g2: org.scalacheck.Gen[List[Int]] = Gen()
    
    scala> g2.sample
    res19: Option[List[Int]] = Some(List(4, 4, 4, 4, 2, 4, 2, 3, 5, 1, 1, 1, 4, 4, 1, 1, 4, 5, 5, 4, 3, 3, 4, 1, 3, 2, 2, 4, 3, 4, 3, 3, 4, 3, 2, 3, 1, 1, 3, 2, 5, 1, 5, 5, 1, 5, 5, 5, 5, 3, 2, 3, 1, 4, 3, 1, 4, 2, 1, 3, 4, 4, 1, 4, 1, 1, 4, 2, 1, 2, 4, 4, 2, 1, 5, 3, 5, 3, 4, 2, 1, 4, 3, 2, 1, 1, 1, 4, 3, 2, 2))
    
    scala> val g3 = Gen.resize(10, g2)
    g3: java.lang.Object with org.scalacheck.Gen[List[Int]] = Gen()
    
    scala> g3.sample
    res0: Option[List[Int]] = Some(List(1))
    
    scala> g3.sample
    res1: Option[List[Int]] = Some(List(4, 2))
    
    scala> g3.sample
    res2: Option[List[Int]] = Some(List(2, 1, 2, 4, 5, 4, 2, 5, 3))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 2018-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多