2016-05-24 10 views
0

Da keine Auswertungen hat:eine Eigenschaft in Scalacheck zum Ausdruck, dass diese verworfen

property("Empty range") { 
    forAll { (min: Int, max: Int) => 
     whenever (min == max) { 
     Range(min, max).size should be (0) 
     } 
    } 
    } 

ich

[info] - Empty range *** FAILED *** 
[info] Gave up after 5 successful property evaluations. 96 evaluations were discarded. 

Wie kann ich meinen Testfall äußern, die die Eigenschaft eines Range zu erfassen ist dass, unabhängig von a und b, wenn sie gleich sind, dann Range(a,b) sollte leer sein.

Ein anderes:

property("10 long range") { 
    forAll { (min: Int, max: Int) => 
     whenever (min < max && (max.toLong-min.toLong).abs == 10) { 
     Range(min, max).head should be (min) 
     } 
    } 
    } 

Ich habe eine Reihe von Testfällen wie folgt aus (für eine Klasse ähnlich wie Range), alle mit dem gleichen Fehler scheitern.

Ich möchte Bereiche mit einer bestimmten Größe erfassen und Elemente innerhalb dieses Bereichs testen - die Idee ist, dass ich möchte, dass ScalaCheck die Bereichsgrenzen für mich generiert.

Antwort

1

Sorry für die verspätete Antwort, aber für den ersten Fall, da bist du nur zu testen, dass der Bereich für zwei passende Werte 0 ist, müssen Sie nur einen Wert generieren:

property("Empty range") { 
    forAll { x: Int => 
    Range(x, x).size should be (0) 
    } 
} 

Durch die Verwendung von ein whenever Fall für diesen Test, die Wahrscheinlichkeit der Generierung von zwei gleichen Werten ist sehr niedrig, so dass Sie eine Menge Kombinationen von min & max verschwenden werden, die nicht gleich sind. Irgendwann wird es aufhören, Kombinationen zu finden, die die Bedingung erfüllen. Die obige Alternative funktioniert für jeden generierten Wert, also auch effizienter.

Das zweite Beispiel ist ähnlich. Zuerst werden alle Fälle, in denen min> = max ist, verworfen. Dann werden alle Fälle, in denen die Differenz zwischen den zwei Werten nicht 10 ist, verworfen. Die Wahrscheinlichkeit, einen min-Wert zu generieren, der genau 10 weniger als der Wert max ist, ist also noch einmal so niedrig, dass der Test nicht mehr versucht, Werte zu finden, die diese Bedingung erfüllen. Wiederum ist das Folgende äquivalent zu dem, was Sie haben und wird für die Mehrheit der generierten Werte funktionieren (nur diejenigen innerhalb von 10 des maximalen Wertes müssen verworfen werden, um einen Überlauf bei der Addition zu vermeiden).

property("10 long range") { 
    forAll { x: Int => 
    whenever (x <= Int.MaxValue - 10) { 
     Range(x, x + 10).head should be (min) 
    } 
    } 
} 

Allerdings scheinen die Tests ein wenig ungewöhnlich zu sein, dass Sie einige sehr spezifische Fälle sind zu testen, wenn Sie stattdessen allgemeinere Bedingungen suchen sollte. Zum Beispiel:

property("Range size") { 
    forAll { (min: Int, max: Int) => 
    whenever (min <= max && (max.toLong - min.toLong) <= Int.MaxValue) { 
     Range(min, max).size should be (max - min) 
    } 
    } 
} 

sollten alle die Größenvergleiche abdecken, einschließlich dem Fall, dass die beiden Werte gleich sind und die Größe ist 0. (Die whenever Klausel in diesem Fall erforderlich ist, min Werte höher als die zu verhindern max Werte und um sicherzustellen, dass die Bereichsgröße nicht die Kapazität eines Int überschreitet). Sie können auch diesen Test schreiben, etwas effizienter in Bezug auf die erzeugten Zahlen, wie folgt aus:

property("Range size #2") { 
    forAll { (a: Int, b: Int) => 
    whenever (Math.abs(a.toLong - b.toLong) <= Int.MaxValue) { 
     val min = Math.min(a, b) 
     val max = Math.max(a, b) 
     Range(min, max).size should be (max - min) 
    } 
    } 
} 

In beiden oben genannten Fällen die whenever Klausel nur versagt gelegentlich - insbesondere im letzteren Fall - eher als praktisch alle die Zeit.