ScalaCheck

ScalaCheck #

Property-based testing #

Property-based testing hat zum Ziel, tests zu specifications zu generalisieren, wobei

  • tests konkrete Beispiele, wie ein Stück Code funktionieren soll, und
  • specifications generelle Definitionen über das Verhalten eines Programms im Allgemeinen sind.

Eng verwandt mit *property-based testing *ist das Konzept tests as specification, welches das Ziel verfolgt, so umfassend Tests zu schreiben, dass diese formale Art der Spezifikation grosse Teile der informellen Art (technische Dokumentation) ersetzen kann. Dies wird auch unter dem Begriff *executable specification *subsummiert. Property-based testing hat eine ähnliche Stossrichtung, wobei der umgekehrte Ansatz verfolgt wird, indem tests Richtung *specifications *(properties) weiterentwickelt werden.

Integration in Gradle #

Scalacheck kann via ScalaTest und JUnit in Gradle integriert werden. Folgend ein Beispiel:

import org.scalatest._
import prop._
import org.scalacheck.Prop.{AnyOperators, forAll, all}
import org.junit.runner.RunWith
import junit.JUnitRunner

object Interleaver {
  def interleave[T](l1: List[T], l2: List[T]): List[T] = {
    if(l1.isEmpty) l2
    else if(l2.isEmpty) l1
    else l1.head :: l2.head :: interleave(l2.tail, l1.tail)
  }
}

@RunWith(classOf[JUnitRunner])
class JustATest extends PropSpec with Checkers {
  property("the interleave method must interleave lists") {
    check(
        forAll { (l1: List[Int], l2: List[Int]) =>
          val res = Interleaver.interleave(l1,l2)
          val is = (0 to Math.min(l1.length, l2.length)-1).toList
          all(
              "length" |: l1.length+l2.length =? res.length,
              "zip l1" |: l1 =? is.map(i => res(2*i)) ++
              res.drop(2*l2.length),
              "zip l2" |: l2 =? is.map(i => res(2*i+1)) ++
              res.drop(2*l1.length)
              ) :| ("res: "+res)
        }
    )
  }
}