1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

概要

ScalaCheckのGenは、プロパティベーステストで使用するテストデータを生成するためのジェネレーターです。
この記事では、Genの様々なメソッドを呼び出した結果について共有します。

const

Gen#constは、引数で指定した値を生成するジェネレータを返します。

scala> Gen.const(1).sample
val res0: Option[Int] = Some(1)

choose

Gen#choose[T]は、第一引数minおよび第二引数maxで閉区間を指定して、
T型の値をランダムに生成するジェネレータを返します。

scala> Gen.choose(0, 10).sample
val res4: Option[Int] = Some(10)

scala> Gen.choose(0, 10).sample
val res8: Option[Int] = Some(2)
                                                                                
scala> Gen.choose(0, 10).sample
val res9: Option[Int] = Some(6)
                                                                                
scala> Gen.choose(0, 10).sample
val res10: Option[Int] = Some(9)
                                                                                
scala> Gen.choose(0, 10).sample
val res11: Option[Int] = Some(0)

fail

Gen#failは、値を絶対に生成しないジェネレータを返します。

scala> Gen.fail.sample
val res2: Option[Nothing] = None
                                                                                
scala> Gen.fail[Int].sample
val res3: Option[Int] = None

個人的に捻り出したGen#failの使い道ですが、
以下のように無効なケースを明示的に扱う場合に使えるかもしれないです。
(他に何かいい使い方があれば教えてくださいm(_ _)m)

無効なケースを明示的に扱う
import org.scalacheck.Prop.forAll
import org.scalacheck.Gen

val validGen: Gen[Int] = Gen.choose(0, 10)
val invalidGen: Gen[Int] = Gen.fail // 0から10までの数字以外はインプットとして想定しないことを強調する

val prop = forAll(Gen.oneOf(validGen, invalidGen)) { n =>
  n >= 0 && n <= 10
}

prop.check()

sequence

Gen#sequenceは、複数のジェネレータを組み合わせて、
それらのジェネレータが生成する値のコレクション(リスト、配列など)を生成するための関数です。

scala> Gen.sequence(List(org.scalacheck.Gen.alphaStr)).sample
val res27: Option[java.util.ArrayList[String]] = Some([ijdWdpIQdxGkKYINKJQ])
scala> import org.scalacheck.Gen.{alphaUpperStr, hexStr}
scala> Gen.sequence(Seq(alphaUpperStr, hexStr)).sample
val res30: Option[java.util.ArrayList[String]] = Some([PJBQKOMHSVFPHPIIVJXOKWPUGHSPLSQDJEFCKC, 76dB30803c6D6C3803404D9Ae44B4B45898B14B6cEce06d2A08Fa42b9c7C233c52B8ec28])

oneOf

Gen.oneOfは、引数として与えられたジェネレータの中からランダムに1つを選び、
そのジェネレータを使って値を生成するジェネレータを返します。

scala> Gen.oneOf(1, 10, 100).sample
val res33: Option[Int] = Some(1)
                                                                                                                                                                                                                                                                                
scala> Gen.oneOf(1, 10, 100).sample
val res34: Option[Int] = Some(100)

scala> Gen.oneOf(Gen.const(1), Gen.const(2)).sample
val res1: Option[Int] = Some(1)

option

Gen.optionは、オプション型の値を生成するためのジェネレータを返します。

scala> Gen.option(1).sample
val res35: Option[Option[Int]] = Some(None)
                                                                                                                                                                                                                                                                                
scala> Gen.option(1).sample
val res36: Option[Option[Int]] = Some(Some(1))

either

Gen.eitherは、Either型の値を生成するためのジェネレータを返します。

scala> Gen.either(100, "aaa").sample
val res41: Option[Either[Int, String]] = Some(Left(100))
                                                                                                                                                                                                                                                                                
scala> Gen.either(100, "aaa").sample
val res42: Option[Either[Int, String]] = Some(Right(aaa))

frequency

Gen.frequencyは、複数のジェネレータとその生成確率をペアにしたリストを受け取り、
指定された確率に従ってジェネレータを選択し、値を生成するジェネレータ返します。

scala> Gen.frequency(
  |   (20, Gen.const(20)),
  |   (80, Gen.const(80))
    | ).sample
val res44: Option[Int] = Some(80)

scala> Gen.frequency(
  |   (20, Gen.const(20)),
  |   (80, Gen.const(80))
    | ).sample
val res45: Option[Int] = Some(80)

scala> Gen.frequency(
  |   (20, Gen.const(20)),
  |   (80, Gen.const(80))
    | ).sample
val res46: Option[Int] = Some(80)

scala> Gen.frequency(
  |   (20, Gen.const(20)),
  |   (80, Gen.const(80))
    | ).sample
val res47: Option[Int] = Some(80)

scala> Gen.frequency(
  |   (20, Gen.const(20)),
  |   (80, Gen.const(80))
    | ).sample
val res48: Option[Int] = Some(20)

listOf

Gen#listOfは、指定されたジェネレータを使って要素を生成し、それらの要素からなるリストを生成するジェネレータを返します。

scala> Gen.listOf(Gen.const(1)).sample
val res2: Option[List[Int]] = Some(List(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1))

scala> Gen.listOf(
     |   Gen.frequency(
     |     (20, Gen.const(20)),
     |     (80, Gen.const(80))
     |   )
     | ).sample
val res4: Option[List[Int]] = Some(List(80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 20, 80, 20, 20, 80, 20, 20, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 20, 80, 20, 80, 80, 80, 80, 20, 20, 20, 80, 80, 20, 80))

scala> res4.get.filter(_ == 20).size.toDouble / res4.get.size
val res6: Double = 0.22916666666666666                                                                         

listOfN

Gen#listOfNは、Gen#listOfとほぼ同じですが、生成するリストの長さを引数で指定できます。

scala> Gen.listOfN(3, Gen.const(1)).sample
val res7: Option[List[Int]] = Some(List(1, 1, 1))
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?