So-net無料ブログ作成
検索選択

ScalaCheck を試す (3) カスタムジェネレータを作る [Scala]

間が空いてしまったけど ScalaCheck を試す続き。

たとえば「任意の整数について」という条件の代わりに「任意の偶数について」など、より限定的な条件を仕様の前提にしたいとする。ひとつの方法は [1] で言及したように ==> を使って前提条件を記述するやりかたがある。でもこの方法だと「任意の整数」を生成した後で前提条件による篩をかけるので無駄が多く、厳しい条件だといつまでたっても有効なテストデータが生成されないということがありうる。

このような場合はカスタムジェネレータを作って最初から有効なデータのみが生成されるようにする。任意の偶数を生成するジェネレータは以下のように書く。

val genEven: Gen[Int] = for (n <- arbitrary[Int]) yield n * 2

for comprehension のジェネレータの部分に ScalaCheck の既存のジェネレータを書くことが出来る。この構文を使ったのはうまいと思う。

ジェネレータを明示的に指定して性質を記述するには forAll を使う。

val propEven = forAll(genEven) (x => x % 2 == 0)

テストの実行はいつもどおり。

scala> check(propEven)
+++ OK, passed 100 tests.
res39: scalacheck.TestStats = TestStats(TestPassed(),100,0)

作成したカスタムジェネレータをその型のデフォルトのジェネレータにするには暗黙の型変換メソッドを書く。以下は Int のデフォルトジェネレータを偶数のみのジェネレータにしてしまう。

scala> check(property((x:Int) => x % 2 == 0))
*** Failed, after 1 successful tests:
The arguments that caused the failure was:
List(-1)

res43: scalacheck.TestStats = TestStats(TestFailed(List(-1)),1,0)

scala> implicit def arbitraryInt(x: Arbitrary[Int]) = genEven
arbitraryInt: (scalacheck.Arbitrary[Int])scalacheck.Gen[Int]

scala> check(property((x:Int) => x % 2 == 0))
+++ OK, passed 100 tests.
res44: scalacheck.TestStats = TestStats(TestPassed(),100,0)

scala> check(property((x:Int) => x % 2 == 0))
+++ OK, passed 100 tests.
res45: scalacheck.TestStats = TestStats(TestPassed(),100,0)

[1] http://blog.so-net.ne.jp/rainyday/2007-08-08-1


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0