2010-09-08 3 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)) 
} 

ничего не объяснил для меня. После некоторого исследования я понял, что длина сгенерированной последовательности не зависит от фактического размера генератора (есть метод изменения размера в объекте Gen, который «создает измененную версию генератора» в соответствии с javadoc (может быть, это означает что-то другое?)).

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 увеличивает параметр размера для каждого тестового прогона. Однако, если вы используете генератор-генератор resize так, как это сделано в Руководстве пользователя ScalaCheck, конечный размер матрицы зависит от линейного параметра размера, что обеспечивает лучшую производительность при тестировании ваших свойств.

Очень часто вам не нужно использовать генераторную комбинацию resize. Если вам нужно сгенерировать списки, ограниченные определенным размером, гораздо лучше сделать что-то вроде приведенного ниже примера, так как нет гарантии, что генераторы действительно используют параметр размера так, как вы ожидаете.

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

Это такой приятный пример, спасибо. Очень показательно. –

+1

Это привело меня к «Gen.frequency ((10, 2), (5, 3), (1, 1)). FlatMap (Gen.listOfN (_, names))', который был именно тем, что мне нужно! –

Смежные вопросы