Markus Günther Selbstständig

Hat ScalaCheck eine Property erfolgreich falsifiziert, versucht es anschließend, die kleinstmögliche Testfallinstanz ausfinding zu machen, die zur Falsifizierung geführt hat.

Über die Jahre ist der Scala-Werkzeugkasten immer weitergewachsen. Mit ScalaCheck kommt eine mächtige Testmethodik in Sachen Property-based Testing dazu. Der Property-basierte Ansatz ist kein Ersatz für beispielbasiertes Testen mittels Unit-Tests. Er ergänzt es vielmehr, vor allem, da Property-based Tests allgemeiner formuliert sind und üblicherweise andere Klassen von Fehlern identifizieren.

Von Anforderungsseite erhalten wir einen Wunsch: Der Fachbereich benötigt eine Funktion, die zwei Ganzzahlen miteinander addieren kann. Nichts einfacher als das, sagt der Entwickler und legt direkt mit der Implementierung los. Die Funktion ist schnell geschrieben, beispielbasierte Unit-Tests sollen die Korrektheit sicherstellen:

class AdderTest extends FlatSpec with Matchers {
  "Adder" should "yield 4 when I add 1 and 3" in {
    add(1, 3) shouldBe 4
  }
  "Adder" should "yield 4 when I add 4 and 0" in {
    add(4, 0) shouldBe 4
  }
}

Doch kurz nach dem Ausrollen des Lieferpakets meldet sich der Betrieb zu Wort: Offenbar scheint es mit dem Addierer Schwierigkeiten zu geben. In der Analyse zeigt sich, dass die implementierte Funktion nicht ganz der Definition des Addierens entspricht.

object Adder {
  def add(a: Int, b: Int) = 4 
}

Offensichtlich decken unsere beispielbasierten Testfälle das korrekte Verhalten des Addierers nur unzureichend ab. Wir haben uns einerseits darauf verlassen, dass unsere Testfälle für eine hinreichende Abdeckung sorgen, und andererseits unsere Implementierung – ganz nach Test-driven Development – minimalistisch ausgerichtet, sodass sie die Testfälle erfüllt.

Zugegeben, dieses Beispiel ist überspitzt, aber das ist in erster Linie der Einfachheit der zu implementierenden Funktion geschuldet. In der Praxis treten solche Erscheinungen dann auf, wenn die Spezifikation unklar ist und der Entwickler ohne Rücksprache mit dem Anforderer seinen Interpretationsspielraum nutzt, oder aber wenn beispielbasierte Tests schlicht unzureichend sind und weder Randfälle noch die bestimmenden Charakteristiken der implementierten Logik prüfen.

Um zurück zu unserem minimalistischen Beispiel zu kommen: Hinterfragen wir zunächst einmal die konkreten Anforderungen an die zu implementierende Funktion. Welche Eigenschaften muss eine Addierfunktion erfüllen? Wir können uns der Sache nähern, indem wir uns anschauen, was einen Addierer von anderen Funktionen, beispielsweise einem Subtrahierer, unterscheidet. Nun, ein Addierer sollte unabhängig von der Reihenfolge der Eingangsparameter dasselbe Resultat liefern. Diese Eigenschaft können wir leicht in Form einer Property mit ScalaCheck formulieren.

Den vollständigen Artikel lesen Sie in der Ausgabe:

Java Magazin 6.18 - "Scala"

Alle Infos zum Heft
579837775Property-based Testing mit ScalaCheck
X
- Gib Deinen Standort ein -
- or -