assert vs. JUnit Assertions

85

Heute habe ich einen JUnit-Testfall mit einer Java-Behauptung anstelle der JUnit-Behauptungen gesehen. Gibt es signifikante Vor- oder Nachteile, die einer gegenüber der anderen vorzuziehen sind?

Robert
quelle
Es gibt absolut sachliche Unterschiede zwischen JUnit-Zusicherungen und dem Java-Schlüsselwort 'assert'. Dies ist überhaupt keine meinungsbasierte Frage.
Thomas W

Antworten:

95

In JUnit4 ist die Ausnahme (tatsächlich Fehler), die von einer JUnit-Zusicherung ausgelöst wird, dieselbe wie der Fehler, der vom Java- assertSchlüsselwort (AssertionError) ausgelöst wird. Sie ist also genau dieselbe wie assertTrueund abgesehen von der Stapelverfolgung, bei der Sie keinen Unterschied feststellen konnten.

Allerdings müssen Asserts in der JVM mit einem speziellen Flag ausgeführt werden, sodass viele Tests bestanden werden, nur weil jemand vergessen hat, das System mit diesem Flag zu konfigurieren, als die JUnit-Tests ausgeführt wurden - nicht gut.

Aus diesem Grund würde ich im Allgemeinen argumentieren, dass die Verwendung von JUnit assertTruedie bessere Vorgehensweise ist, da sie garantiert, dass der Test ausgeführt wird, Konsistenz gewährleistet (Sie verwenden manchmal assertThatoder andere Asserts, die kein Java-Schlüsselwort sind) und wenn das Verhalten von JUnit Asserts ist Sollte sich dies in Zukunft ändern (z. B. durch Einbinden in einen Filter oder eine andere zukünftige JUnit-Funktion), kann Ihr Code dies nutzen.

Der eigentliche Zweck des Assert-Schlüsselworts in Java besteht darin, es ohne Laufzeitstrafe deaktivieren zu können. Das gilt nicht für Unit-Tests.

Yishai
quelle
26

Ich bevorzuge JUnit-Zusicherungen, da sie eine umfangreichere API bieten als die integrierte assertAnweisung und, was noch wichtiger ist, nicht explizit aktiviert werden müssen, im Gegensatz dazu assert, was das -eaJVM-Argument erfordert .

Adamski
quelle
1
-eaist immer aktiviert in mvn test, keine Notwendigkeit für -ea. Reichere API, guter Fang. Manchmal denke ich, dass API im Test missbraucht wird, weil sie nicht Teil der Anwendung ist (a in api). Ich ziehe es vor, sie nur als umfangreichere Methoden zu bezeichnen.
Grimmig
19

Wenn ein Test fehlschlägt, erhalten Sie mehr Informationen.

assertEquals(1, 2); führt zu java.lang.AssertionError: expected:<1> but was:<2>

vs.

assert(1 == 2); führt zu java.lang.AssertionError

Sie können noch mehr Informationen erhalten, wenn Sie das Nachrichtenargument hinzufügen assertEquals

Starmer
quelle
9
versuche es assert 1==2: "1 is not 2";.
Grim
@PeterRader Versuchen Sie das Schlüsselwort assert, wenn -ea nicht aktiviert ist. Oder noch besser, verwenden Sie JUnit-Zusicherungen, die immer funktionieren.
Thomas W
1
@ThomasW Wenn -ea nicht aktiviert ist, ist es kein Test. JUnit-Asserationen funktionieren nicht immer, sie funktionieren nur, wenn Sie sich für die Verwendung von JUnit als Framework entscheiden, und im Fall von Maven eine Maven-Abhängigkeit, eine Maven-Abhängigkeit, die nur im Testbereich liegen muss. Wir haben hier zwei Seiten: Was bevorzugen Sie? 1. Seite : Verwenden Sie ein Framework, das nur als Abhängigkeit im Testbereich heruntergeladen werden muss und das Sie mit Eclipse in Klassen verwenden können, die sich nicht im Ordner src / main befinden, aber dort nicht kompiliert werden, da maven junit nur in test- haben. Umfang oder 2. Seite : Verwenden Sie das eingebaute Material.
Grimmig
1
@PeterRader Diese Frage bezieht sich auf JUnit-Testfälle. In diesem Zusammenhang sollte JUnit oder eine ähnliche Assertionsklasse verwendet werden, da diese immer aktiviert sind. Ich bin persönlich von dem Java-Schlüsselwort "assert" überrascht worden, das in der Vergangenheit nicht aktiviert wurde, und glaube nicht, dass unzuverlässige Zusicherungen einen Platz im Testcode haben.
Thomas W
Im separaten Kontext von Zusicherungen im Feature-Code - wichtig für eine robuste Programmierpraxis, aber nicht das eigentliche Thema der Frage - haben sowohl Spring als auch Google Guava Zusicherungsklassen, die immer aktiviert sind. Ich empfehle die großzügige Verwendung dieser als Parameter- und Zustandsvoraussetzungen, um die Richtigkeit sicherzustellen. Darüber hinaus kann es in leistungskritischen Bereichen einen kleinen Bereich geben, in dem Java assertmöglicherweise vorzuziehen ist - für Korrektheitsprüfungen, die sich auf die Leistung auswirken und daher am besten standardmäßig deaktiviert werden. Ich habe jedoch die Erfahrung gemacht, dass die meisten Behauptungen immer gültig sein sollten.
Thomas W
8

Ich würde sagen, verwenden Sie JUnit-Asserts in Testfällen und Java's Assert im Code. Mit anderen Worten, realer Code darf niemals JUnit-Abhängigkeiten aufweisen, wie offensichtlich, und wenn es sich um einen Test handelt, sollte er die JUnit-Variationen verwenden, niemals die Behauptung.

Bruno D. Rodrigues
quelle
0

Ich würde sagen, wenn Sie JUnit verwenden, sollten Sie die JUnit-Zusicherungen verwenden. assertTrue()ist im Grunde das gleiche wie assert, sonst warum überhaupt JUnit verwenden?

CheesePls
quelle
4
Sie würden JUnit für das Testlauf-Framework verwenden. Behauptungen sind wirklich ein kleiner Teil des Wertes, den JUnit Ihnen gibt. JUnit ohne Assertwürde mehr Boilerplate erfordern. assertOhne JUnit müssten Sie ein ganzes Framework schreiben.
Yishai
1
Ich habe eher gesagt, wenn Sie das Tool verwenden wollen, verwenden Sie das Werkzeug. Regelmäßige alte Assert-Aussagen scheinen in JUnit-Testfällen ein bisschen albern zu sein. Sie gehören meiner Meinung nach zum eigentlichen Code.
CheesePls
1
@CheesePls "reguläre alte Assert-Anweisungen" sind in der Tat aktueller als JUnit-Asserts.
Dolmen
0

Dies gilt möglicherweise nicht, wenn Sie ausschließlich glänzende und neue Inhalte verwenden, aber assert wurde erst in 1.4SE in Java eingeführt. Wenn Sie in einer Umgebung mit älterer Technologie arbeiten müssen, können Sie sich aus Kompatibilitätsgründen an JUnit wenden.

Dan Coates
quelle