Einführende Beispiele QuickCheck
Übersicht: Einführende Beispiele QuickCheck
Einführung
Alle hier und im weiteren Verlauf der Ausarbeitung aufgeführten Beispiele werden iterativ entwickelt, und die einzelnen Schritte der Entwicklung werden dargestellt. Dabei ist das Ziel, dem Leser es zu ermöglichen die vollständige Entwicklung des Codes nachzuvollziehen.
Es wird nach folgendem Muster verfahren:
- Einführung in die Thematik,
- Vorstellung der allgmeinen Ideen
- [Vorstellung der Umsetzung]
- [Überprüfung der Umsetzung]
- [Verbesserung der Umsetzung]
[] die mit eckigen Klammern ausgezeichneten Anteile werden iterativ wiederholt
Formulierung einer Eigenschaft
Als erstes, einleitendes Beispiel formulieren wir folgenden Test bzw. formulieren wir eine erste Eigenschaft.
01 import QuickCheck
02
03 prop_PlusAssociative x y z =
04 (x + y) + z == x + (y + z)
|
plusAsso1.hs |
Codebeispiel 1
Es handlet sich um den Test bezüglich der Assoziativität des (+) Operators. Die Assoziativität gibt an, ob eine Folge von Operatoren gleichen Vorrangs von links oder von rechts abgearbeitet wird.
Wir sehen in Übereinstimmung mit bekannten UnitTestFrameworks wird auch in QuickCheck mit einer Namenskonvention
für die Benennung der Tests, genauer der Eigenschaften gearbeitet. Alle Eigenschaften werden mit "prop_..." benannt, so dass es möglich ist, auf basis eines Skriptes alle Tests in einen Modul automatisch zu identifizieren und auszuführen.
Die Ausführung des Test erzeugt einen Fehler. QuickCheck ist nicht in der Lage die notwendigen Testdaten zu generieren. Es fehlt eine Typsignatur, anhand derer für QuickCheck klar ersichtlich wird welchen Typ die Testdaten haben müssen.
Main> quickCheck prop_PlusAssociative
ERROR - Unresolved overloading
*** Type : (Num a, Arbitrary a) => IO ()
*** Expression : quickCheck prop_PlusAssociative
Aus dem o.g. Beispiel ersehen wir die Bedeutung der Typsignatur bei der Formulierung einer Eigenschaft. Wir erweitern unsere Eigenschaft entsprechend.
01 import QuickCheck
02
03 prop_PlusAssociative :: Integer -> Integer -> Integer -> Bool
04 prop_PlusAssociative x y z =
05 (x + y) + z == x + (y + z)
|
plusAsso2.hs |
Codebeispiel 2
Main> quickCheck prop_PlusAssociative
OK, passed 100 tests.
Mit der der Typsignatur kann der Test erfolgreich durchgeführt werden.
Die Typsignatur ist zwingend erforderlich für das Generieren der Testdaten mit / durch QuickCheck.
Wir erweitern den Test auf den Wertebereich der Fließkommazahlen und formilieren:
01 import QuickCheck
02
03 prop_PlusAssoInt :: Integer -> Integer -> Integer -> Bool
04 prop_PlusAssoInt x y z =
05 (x + y) + z == x + (y + z)
06
07 prop_PlusAssoFloat :: Float -> Float -> Float -> Bool
08 prop_PlusAssoFloat x y z =
09 (x + y) + z == x + (y + z)
10
11 prop_PlusAssoDouble :: Double -> Double -> Double -> Bool
12 prop_PlusAssoDouble x y z =
13 (x + y) + z == x + (y + z)
|
plusAsso3.hs |
Codebeispiel 3
Main> quickCheck prop_PlusAssoInt
OK, passed 100 tests.
Main> quickCheck prop_PlusAssoFloat
Falsifiable, after 25 tests:
-6.66667
8.0
-2.33333
Wir stellen durch das Auftreten dieses Fehlers fest, dass der Datentyp in diesem Fall relevant für Testergebnis ist. Die Addition von Fließkommazahlen ist nicht Assoziativ (Rundungsfehler) --> Bedeutung des Datentyps bei der Formulierung einer Eigenschaft
Code generated with AusarbeitungGenerator Version 1.1, weblink