Specs und ScalaTest sind beide gute Tools für zufriedene Benutzer, unterscheiden sich jedoch in mehrfacher Hinsicht. Sie werden wahrscheinlich eines als Haupttestwerkzeug in Scala auswählen wollen, müssen aber das andere nicht aufgeben, da Sie Teile von beiden verwenden können. Wenn Sie ScalaTest mögenFeatureSpec
Syntax von und die Mockito-Syntax von , können Sie beide JAR-Dateien in Ihren Klassenpfad einfügen und beide gleichzeitig verwenden. Hier werde ich versuchen, die wichtigsten Unterschiede in der Designphilosophie zu erfassen, die ich zwischen den Spezifikationen und ScalaTest festgestellt habe.
Wahrscheinlich besteht der wichtigste philosophische Unterschied zwischen den Tools darin, dass Spezifikationen für die verhaltensgesteuerte Entwicklung (BDD) entwickelt wurden, während ScalaTest allgemeiner ist. ScalaTest bietet Eigenschaften, die Sie mischen können, um das Verhalten zu erhalten, das Sie in Ihren Testklassen bevorzugen, einschließlich BDD. Sie können auch einfach Ihr eigenes Verhalten definieren, wenn Sie etwas anderes möchten.
ScalaTest unterstützt BDD durch seine Spec
, FeatureSpec
, WordSpec
, FlatSpec
, und GivenWhenThen
Züge, und hat auch Eigenschaften , die Sie mischen in kann eine schöne Matcher Syntax zu erhalten. Wenn Sie "sollte" mögen, mischen Sie ShouldMatchers ein. Wenn Sie "muss" mögen, mischen Sie ein MustMatchers
. Wenn Sie BDD mögen, aber keine Matcher-Syntax mögen, können Sie einfach eines der ScalaTest-Spec-Merkmale verwenden, ohne ein Matcher-Merkmal einzumischen. Specs hat eine Specification-Klasse, die Sie erweitern, und Sie müssen das Wort "must" in Ihren Matcher-Ausdrücken verwenden. Ein großer philosophischer Unterschied, der hier offensichtlich ist, ist, dass ScalaTest Ihnen viel mehr Auswahlmöglichkeiten bietet. Um die Navigation in diesem Bereich Ihrer Wahl zu vereinfachen, stelle ich hier einen Entscheidungsbaum bereit:
http://www.scalatest.org/quick_start
Die Matcher-Syntax unterscheidet sich auch zwischen ScalaTest und Spezifikationen. In ScalaTest habe ich versucht zu sehen, wie weit ich mit der Operator-Notation gehen kann, und am Ende habe ich Matcher-Ausdrücke gefunden, die sich sehr ähnlich wie englische Sätze mit Leerzeichen zwischen den Wörtern lesen. Die Syntax des Specs Matchers führt Wörter mehr zusammen mit der Groß- und Kleinschreibung des Kamels aus.
Specs hat mehr Matcher als ScalaTest und das spiegelt meiner Meinung nach einen Unterschied in der Designeinstellung wider. Ich habe wahrscheinlich 2/3 der Matcher-Syntax geschnitten, die ich erstellt und für die Veröffentlichung in Betracht gezogen habe. Ich werde in zukünftigen Versionen weitere Matcher hinzufügen, wollte aber sichergehen, dass ich wusste, dass Benutzer tatsächlich etwas wollten, bevor ich es hinzufügte. Die Matcher von ScalaTest enthalten jedoch eine dynamische Eigenschafts-Matcher-Syntax, die einen Teil dieser Lücke einnimmt. Zum Beispiel können Sie in Specs schreiben auf java.io.File
:
file must beDirectory
Dadurch wird das aufgerufen isDirectory
und sichergestellt, dass es wahr ist. ScalaTest hat java.io.Files
derzeit keine speziellen Matcher , aber in ScalaTest können Sie einfach eine dynamische Prüfung wie die folgende verwenden:
file must be a ('directory)
Jedes Mal, wenn Sie ein Symbol nachher übergeben be
, wird mithilfe der Reflexion (in diesem Fall) nach einer Methode oder einem Feld mit dem Namen directory
oder einer Methode mit dem Namen gesucht isDirectory
. Es gibt auch eine Möglichkeit, dies statisch zu machen, indem Sie a definieren BePropertyMatcher
(was normalerweise nur 2 oder 3 Codezeilen erfordert). Grundsätzlich versuche ich in ScalaTest, mehr Funktionalität mit weniger API bereitzustellen.
Ein weiterer allgemeiner Unterschied in der Designeinstellung zwischen Spezifikationen und ScalaTest betrifft implizite Konvertierungen. Standardmäßig erhalten Sie bei Verwendung von ScalaTest nur eine implizite Konvertierung, bei der der ===
Operator auf alles angewendet wird . (Wenn nötig, können Sie diese implizite Konvertierung mit einer Codezeile "deaktivieren". Der einzige Grund, warum Sie dies tun müssten, wäre, wenn Sie versuchen würden, etwas zu testen, das einen eigenen ===
Operator hat, und Sie einen Konflikt erhalten. ) ScalaTest definiert viele andere implizite Konvertierungen. Um sie jedoch zu verwenden, müssen Sie sie explizit in Ihren Code "einladen", indem Sie ein Merkmal einmischen oder einen Import durchführen. Wenn Sie die Klasse erweiternSpecification
Ich denke, Sie erhalten standardmäßig Dutzende impliziter Konvertierungen. Ich bin mir nicht sicher, wie wichtig dies in der Praxis sein wird, aber ich denke, die Leute werden Code testen wollen, der ihre eigenen Implikationen verwendet, und manchmal kann es einen Konflikt zwischen den Implikationen des Testframeworks und denen des Produktionscodes geben. In diesem Fall ist es möglicherweise einfacher, das Problem in ScalaTest zu umgehen als die Spezifikationen.
Ein weiterer Unterschied in der Designeinstellung, den ich bemerkt habe, ist der Komfort bei den Bedienern. Ein Ziel, das ich hatte, war, dass jeder Programmierer, der sich den Testcode eines anderen ansieht, der ScalaTest verwendet, die Bedeutung erraten kann, ohne etwas in der ScalaTest-Dokumentation nachzuschlagen. Ich wollte, dass der ScalaTest-Clientcode absolut offensichtlich ist. Ein Weg, wie sich dieses Ziel manifestierte, ist, dass ScalaTest den Betreibern gegenüber sehr konservativ ist. Ich definiere nur fünf Operatoren in ScalaTest:
===
, was bedeutet gleich
>
, was bedeutet größer als
<
, weniger als
>=
, größer als oder gleich
<=
, weniger als oder gleich.
Das ist es. Diese Dinge sehen also so ziemlich so aus, wie sie bedeuten. Wenn Sie im Code eines anderen sehen:
result should be <= 7
Ich hoffe, dass Sie nicht zur API-Dokumentation gehen müssen, um zu erraten, was das <=
bedeutet. Im Gegensatz dazu sind die technischen Daten bei den Betreibern viel freier. Daran ist nichts auszusetzen, aber es ist ein Unterschied. Die Betreiber können Code prägnanter machen, aber der Kompromiss ist , dass Sie in der Dokumentation laufen müssen, wenn Sie Dinge wie finden ->-
, >>
, |
, |>
, !
, oder ^^^
(die alle eine besondere Bedeutung in Specs haben) in Testcode Ihres Kollegen.
Ein anderer philosophischer Unterschied ist , dass ich versuche und mache es einfach etwas leichter in ScalaTest einen funktionalen Stil zu verwenden , wenn Sie benötigen eine Befestigung zu teilen, während Specs standardmäßig die Tradition der weiter setUp
und tearDown
nähert von JUnit populär, in dem Sie Umhang Vars vor jedem Test. Wenn Sie jedoch auf diese Weise testen möchten, ist dies auch in ScalaTest sehr einfach. Sie müssen nur das BeforeAndAfter
Merkmal einmischen.
Weitere Informationen zu ScalaTest finden Sie in der Präsentation "Get Higher with ScalaTest", die ich auf der Devoxx-Konferenz 2009 hier gehalten habe:
http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about