11

いくつかのランダムな値に加えて、少なくとも固定された一連の特別な値を使用して、すべてのプロパティを常にテストする必要があります。これは、そのジェネレータータイプを使用するすべてのテストではなく、ジェネレーター仕様で定義したいと思います。たとえば、Intを生成する場合、ジェネレーターでテストケースごとに少なくとも0、1、および-1を常に生成するようにします。これは可能ですか?

私がこれまでに思いついた最善の方法は、最小のnサイズが私のn個の特殊なケースに対応するサイズのジェネレーターを作成することです。これは、少なくとも、テストの最大数が最大サイズパラメータよりも少なくなるように構成されている場合、すべての可能なサイズがテストされないため、問題があります。

4

2 に答える 2

19

まず第一に、Scalacheckにはすでにバイアスがあり、0、1、-1でInt.MaxValueありInt.MinValue、他のInt値に加えて選択される可能性が非常に高くなります。だから、それがあなたの心配なら、心配しないでください。同様に、空の文字列が生成される可能性があります。

ただし、この動作を他の何かのために再現したい場合は、Gen.oneOfまたはGen.frequencyを、おそらくと組み合わせて使用​​してGen.chooseください。oneOffrequencyをパラメーターとして使用するためGen、特殊なケースを汎用ジェネレーターと組み合わせることができます。

例えば:

val myArb: Arbitrary[Int] = Arbitrary(Gen.frequency(
    1 -> -1, 
    1 ->  0, 
    1 -> 1, 
    3 -> Arbitrary.arbInt.arbitrary
))

任意のintの可能性が50%(私が話したバイアスが伴う)で、-1、0、および1のそれぞれに対して16.6%で、あなたが要求したことをほぼ実行します。

于 2011-09-28T00:47:16.507 に答える
1

私は今日同じ質問をしてここに行き着いたので、次のように、Propを使用する前に私の特別なケースのを生成するという私の解決策を追加すると思いましGenた:

import org.scalacheck.Gen.{alphaChar, const}
import org.scalacheck.Prop.{forAll, passed}
import org.scalacheck.{Gen, Prop}

// evaluate fn first with some initial values, then with some generated ones
def forAllAfter[A](init: A*)(subsequent: Gen[A])(fn: A => Prop): Prop =
  init.foldLeft(passed) { case (p, i) => p && forAll(const(i))(fn) } && forAll(subsequent)(fn) 

// example of usage
val prop = forAllAfter('a', 'b', 'c')(alphaChar) { c =>
  println(c) 
  passed
}

ここでのforAllAfter関数は、最初にテストする必要のある値ごとにPropsを作成し、次にそれらを後続の値のジェネレーターを使用して作成された小道具と組み合わせてテストします。Gen.const

使用している場合は、次のように結果を評価するために、特性をテストにScalaTest混合する必要があります。CheckersProp

import org.scalatest.WordSpec
import org.scalatest.prop.Checkers
import org.scalacheck.Gen.{alphaChar, const}
import org.scalacheck.Prop.{forAll, passed}
import org.scalacheck.{Gen, Prop}

class TestExample extends WordSpec with Checkers {

  def forAllAfter[A](init: A*)(subsequent: Gen[A])(fn: A => Prop): Prop =
    init.foldLeft(passed) { case (p, i) => p && forAll(const(i))(fn) } && forAll(subsequent)(fn)

  val prop: Prop = forAllAfter('a', 'b', 'c')(alphaChar) { c =>
    println(c)
    passed
  }

  "Test example" should {
    "Work correctly" in {
      check(prop)
    }
  }
}
于 2018-11-29T23:31:04.750 に答える