SSブログ

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

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。