LoginSignup
3
5

More than 5 years have passed since last update.

ScalaCheckで独自のGeneratorを作る

Posted at

概要

ScalaCheckはPropertyベースのテスト用ライブラリです。

ランダムなパラメータを生成し、テスト対象の関数の振る舞いをテストします。

標準で文字列や数値をランダムに生成する便利なGeneratorがありますが、独自のGeneratorを作成することも可能です。

この記事では独自にGeneratorを作成してみます。

事前準備

ScalaCheckを使えるようにするため、build.sbtに以下を追加します

build.sbt
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.5" % "test"

検査対象クラス

今回は以下のようなクラスでテストしてみます

MyClass.scala
case class MyClass(number: Int, multiplier: Multiplier) {

  def calc: Int = {
    number * multiplier.number
  }
}

case class Multiplier(number: Int)

MyClassはnumbermultiplierというメンバ変数を持っていて、calcメソッドでnumbermultiplierを掛けた値を返します。

また、Multiplierはnumberをメンバ変数に持つようにしています。

テストクラス

検査対象クラスに対してテストクラスは以下のように書いてみました。

MyClassTest.scala
import org.scalacheck.{Arbitrary, Gen, Prop, Properties}

object MyClassTest extends Properties("MyClass") {

  // MultiplierのGenerator
  // -1000 ~ 1000のnumberを持つMultiplierを生成します
  val genMultiplier: Gen[Multiplier] = for {
    number <- Gen.chooseNum(-1000, 1000)
  } yield Multiplier(number)

  // MyClassのGenerator
  // -1000 ~ 1000のnumberとgenMultiplierで生成したMultiplierを持つMyClassを生成します
  val genMyClass: Gen[MyClass] = for {
    number <- Gen.chooseNum(-1000, 1000)
    multiplier <- genMultiplier
  } yield MyClass(number, multiplier)

  // Prop.forAllでMyClassの乱数を呼び出す際にArbitraryを定義
  implicit val arbMyClass = Arbitrary {genMyClass}

  // テストの実行
  // 100パターンのMyClassをランダムに生成してcalcの挙動を
  property("calc") = Prop.forAll{(myClass: MyClass) =>
    myClass.calc == myClass.number * myClass.multiplier.number
  }

}

これでテストを実行してみます

$ sbt test
~
[info] + MyClass.calc: OK, passed 100 tests.
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 4 s, completed 2016/01/28 11:28:23

うまくいったみたいですね <3

3
5
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
3
5