Gibt es eine bequeme Möglichkeit, Tests auf mehrere Datensätze ausführen - wie in JUnit's parametrisierte Tests?
Antworten
Zu viele Anzeigen?In ScalaTest 1.5 wird es eine neue Funktion zum Testen mehrerer Datensätze geben, die Sie derzeit als Snapshot ausprobieren können. Sie wird auf scala-tools.org veröffentlicht:
Gruppen-ID: org.scalatest Artefakt-ID: scalatest Version: 1.5-SNAPSHOT
Sie mischen in (oder importieren die Mitglieder von) TableDrivenPropertyChecks, dann können Sie Tabellen wie diese definieren:
val examples =
Table(
("a", "b", "c", "d"),
( 1, 1, 1, 1),
( 1, 1, 1, 1),
( 1, 1, 1, 1),
( 1, 1, 1, 1)
)
Sie übergeben eine var arg Liste von Tupeln an Table. Jedes Tupel muss die gleiche Arität haben, in diesem Fall hat jedes Tupel die Arität 4 (4 Mitglieder). Das erste Tupel besteht aus Strings, die Namen für die Spalten definieren. Die nachfolgenden Tupel definieren jeweils eine Datenzeile. Sie können jeden Typ in das Tupel aufnehmen, aber im Allgemeinen enthält jede Spalte denselben Typ. Wenn Sie wollen, können Sie aber auch Spalten vom Typ Any haben, die alles enthalten können. Sie können eine Tabelle mit 1 bis 22 Spalten haben. Wenn Sie mehr als 22 Spalten benötigen (die maximale Tupelgröße in Scala ist derzeit 22), können Sie einen zusammengesetzten Typ in einer oder mehreren Spalten verwenden.
Sobald Sie eine Tabelle haben, können Sie sie mit forAll wie folgt überprüfen:
forAll (examples) { (a, b, c, d) =>
a + b + c + d should equal (4)
}
forAll benötigt zwei Parameterlisten. Die erste ist eine Tabelle und die zweite ist eine "Eigenschaftsfunktion", die etwas ausdrückt, das für jede Zeile der Tabelle zutreffen sollte. forAll nimmt jede Zeile der Tabelle (wobei die Überschriftenzeile mit den Spaltennamen natürlich übersprungen wird) und überprüft, ob die Eigenschaft zutrifft. Wenn dies nicht der Fall ist, erhalten Sie eine nette Fehlermeldung, die angibt, welche Zeile der Tabelle fehlgeschlagen ist, wie die Werte der genannten Spalten lauten usw.
Eine Tabelle ist eine Seq der Daten-Tupel, so dass man sie auch wie eine Seq verwenden kann. Sie könnten zum Beispiel eine Seq von Option[Exception] erhalten, die angibt, welche Zeilen fehlgeschlagen sind, wie folgt:
for ((a, b, c, d) <- examples) yield {
failureOf { a + b + c + d should equal (4) }
}
Die resultierende Seq enthält eine Option für jede Datenzeile in der Tabelle, bei der es sich um eine None handelt, wenn die Eigenschaft für diese Zeile bestanden hat, und um Some[Exception], wenn die Eigenschaft nicht bestanden hat. Die Ausnahme in Some enthält alle Einzelheiten über den Fehler.
Eine weitere Möglichkeit für datengesteuerte Tests ist die Verwendung der folgenden Syntax:
class SampleTest extends FunSuite {
val input = List((1, 1), (4, 2), (9, 3))
input.foreach{i =>
test(s"Test of math.sqrt(${i._1})") {
assert(math.sqrt(i._1) === i._2)
}
}
}
Tests werden standardmäßig parallel ausgeführt, es sei denn, Sie setzen in build.sbt parallelExecution in Test := false
.
Gemeinsame Tests kann für Sie interessant sein. Sie ermöglichen es Ihnen, eine Reihe von Tests zu definieren, wie in diesem Stack-Beispiel:
def nonEmptyStack(stack: Stack[Int], lastItemAdded: Int) {
"be non-empty" in {
assert(!stack.empty)
}
"return the top item on peek" in {
assert(stack.peek === lastItemAdded)
}
"not remove the top item on peek" in {
val size = stack.size
assert(stack.peek === lastItemAdded)
assert(stack.size === size)
}
"remove the top item on pop" in {
val size = stack.size
assert(stack.pop === lastItemAdded)
assert(stack.size === size - 1)
}
}
und dann in der eigentlichen Spezifikation können Sie es so verwenden:
behave like nonEmptyStack(stackWithOneItem, lastValuePushed)
Mit anderen Worten nonEmptyStack ist eine parametrisierte Reihe von Tests, die Sie mit verschiedenen Datensätzen, die Sie testen möchten, verwenden können.
0 Stimmen
Ich würde einen Blick auf Scalacheck werfen, das von Scalatest verwendet werden kann.