2010-09-08 33 views
14

UserGuide提到大小的发电机scalacheck项目。解释码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 

你能解释我发生了什么我错过了,给我一些例子,你是如何在测试代码中使用它们?

回答

9

您使用的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)) 
18

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

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

您应该不必非常频繁地使用resize发生器组合器。如果你需要生成一些特定大小的列表,最好是像下面的例子那样做,因为不能保证发生器真正按照你期望的方式使用size参数。

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

这是一个很好的例子,谢谢。很说明。 – 2011-02-14 23:01:55

+1

这让我变成了Gen.frequency((10,2),(5,3),(1,1))。flatMap(Gen.listOfN(_,names))'这正是我所需要的! – 2014-09-11 12:16:49