wake-up-neo.net

Soll in der JUnit-Nachricht der Erfolg oder Misserfolg angegeben werden?

Ich kann eine Bestätigungsnachricht auf zwei Arten schreiben. Erfolg angeben:

assertEquals( "objects should be identical", expected, actual );

Oder den Zustand des Bruches angeben:

assertEquals( "objects aren't identical", expected, actual );

Gibt es hierfür einen Standard in JUnit? Wenn nein, was sind die Argumente für jede Seite?

P.S. Ich habe Artikel im Internet gesehen, in denen beide ohne Erklärung dargestellt wurden. Wenn Sie also "Google durchsuchen" sagen, ist dies keine Antwort!

[UPDATE]

Jeder wird auf die Tatsache aufgehängt, dass ich assertEquals verwendet habe, und daher ist die Nachricht wahrscheinlich nutzlos. Aber das liegt natürlich nur daran, dass ich die Frage einfach veranschaulichen wollte.

Stellen Sie sich stattdessen vor:

assertTrue( ... big long multi-line expression ... );

Wo eine Nachricht nützlich ist.

60
Jason Cohen

Ich mache selten eine Nachricht, zumindest für assertEquals. Jeder vernünftige Testläufer wird erklären, dass Sie assertEquals verwendet haben und die beiden Dinge, die gleich sein sollten. Keine Ihrer Nachrichten enthält mehr Informationen.

Normalerweise stelle ich fest, dass Ausfälle von Komponententests nur vorübergehende Probleme sind. Das "Herausfinden, was falsch ist" beinhaltet normalerweise so viele Details, dass eine einzelne Nachricht keinen großen Unterschied macht. Betrachten Sie "Zeit durch eine Nachricht gespart" vs "Zeit für das Nachdenken über Nachrichten" :)

BEARBEITEN: Okay, ein Fall, in dem ich könnte eine Nachricht verwenden: wenn es eine kompakte Beschreibung im Text gibt, die aus der String-Darstellung des Objekts nicht ersichtlich ist.

Beispiel: "Voraussichtliches Datum ist der 1. Dezember", wenn als Millisekunden gespeicherte Daten verglichen werden.

Ich würde mir keine Sorgen darüber machen, wie Sie es genau ausdrücken: Stellen Sie einfach sicher, dass es aus der Botschaft ersichtlich ist, auf welche Weise Sie das meinen. Entweder "sollte" oder "war nicht" ist in Ordnung - nur "1. Dezember" wäre nicht offensichtlich.

30
Jon Skeet

Gemäß der junit-API ist die Nachricht die "identifizierende Nachricht für den AssertionError". Es handelt sich also nicht um eine Nachricht, die die Bedingung beschreibt, die erfüllt werden sollte, sondern eine Nachricht, die beschreibt, was falsch ist, wenn die Bedingung nicht erfüllt ist. In Ihrem Beispiel scheint "Objekte nicht identisch" zu sein.

21
Reto Gmür

Im Gegensatz zu vielen anderen ist die Verwendung einer Nachricht aus vielen Gründen äußerst hilfreich:

  1. Die Person, die die Protokolle eines fehlgeschlagenen Tests betrachtet, ist möglicherweise nicht die Person, die den Test geschrieben hat. Es kann einige Zeit dauern, den Code durchzulesen und zu verstehen, welchen Fall die Behauptung betreffen soll. Eine hilfreiche Nachricht spart Zeit.

  2. Selbst wenn der Entwickler des Tests sich die Protokolle ansieht, kann es Tage oder Monate her sein, seit der Test geschrieben wurde, und eine Nachricht kann wiederum Zeit sparen.

Mein Rat wäre, die Nachricht mit einer Erklärung des erwarteten Verhaltens zu schreiben. Zum Beispiel:

assertEquals("The method should be invoked 3 times", 3, invocationCount);
9
Matt Accola

Ich glaube nicht, dass es überhaupt etwas bedeutet. Sie wissen bereits, dass ein Fehler aufgetreten ist. Daher ist es egal, ob in der Nachricht angegeben ist, was hätte passieren sollen oder was nicht passieren sollte. 

Das Ziel der Nachricht ist es, Ihnen zu helfen, wann immer es möglich ist, nicht um etwas Vollständigkeit zu erhalten. 

Offensichtlich ist dies bei assertEquals weniger wichtig, aber bei allgemeinen Asserts ist die Nachricht wichtig. Die Nachricht sollte Ihnen helfen, genügend Kontext zu erhalten, um sofort zu verstehen, was genau fehlgeschlagen ist. 

Die Menge des benötigten Kontexts (und damit die Details in der Nachricht) sollte jedoch davon abhängen, wie Sie den Bericht abrufen. Wenn Sie es zum Beispiel in Eclipse erhalten, können Sie leicht auf die Interaktion zugreifen und sehen, was passiert ist, sodass die Nachricht weniger wichtig ist. Wenn Sie jedoch Ihre Berichte per E-Mail erhalten (z. B. von einem Continuous Build-Server), möchten Sie, dass die Nachricht genügend Informationen enthält, damit Sie eine Vorstellung davon haben, was los ist, bevor Sie den entsprechenden Quellcode aufrufen.

3
Uri

Ich möchte die Frage beantworten, ohne zu überlegen, ob eine generelle Nachricht nützlich ist.

Wenn ein Test fehlschlägt, stimmt etwas nicht. Ich weiß das. Ich möchte wissen, warum es kaputt ist. Das ist sehr leicht herauszufinden, da ich nur den Testfall und den SUT öffnen muss. Wie Jon sagte, ist es sehr einfach, das Problem zu beheben (hoffentlich ;-)).

Aber was ist mit der Nachricht? Die Botschaft ist für mich ein Hinweis, was man tun könnte, um daraus einen grünen Testfall zu machen. Ich würde mich daher freuen, wenn der Nachrichtentext einen Rat enthält, wie dieses Problem behoben werden kann oder wo das Problem zu suchen ist.

Ein weiterer interessanter Aspekt wäre die Verwendung von positiven Ausdrücken. Es ist eine Überlegung wert, positive Textnachrichten zu verwenden. In Ihrem Beispiel würde ich Objects should be identical verwenden. Aber das ist ein kleiner Grund.

3
guerda

Entsprechend den Spezifikationen soll die Nachricht den Fehler beschreiben, wenn er auftritt .. _. Und er ist nützlich, wenn Sie Ihre Anwendung in einer CI-Umgebung wie Jenkins erstellen und Plugins verwenden, um Fehlerergebnisse zu analysieren.

http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertTrue(Java.lang.String,%20boolean)

message - die identifizierende Nachricht für den AssertionError (null okay)

2
Wander Costa

Ich sehe diese Frage aus zwei Perspektiven, 

Erste und häufigste Perspektive, die von den meisten von uns hier bereits diskutiert wird: Aus der Perspektive einer Person, die die Protokolle sieht und versucht, den Fehler zu beheben: Ich glaube, dass beide Nachrichten das Gleiche bieten Information.

Die zweite Perspektive bezieht sich auf jemanden, der den Code liest/verwaltet/überprüft: Wie wir schon seit Ewigkeiten sprechen, ist die Lesbarkeit und Einfachheit des Codes. Also ist es auch gleich wichtig.

Wir sind überzeugt, dass mein Code einfach und selbsterklärend sein sollte, so dass keine expliziten Kommentare erforderlich sind, und ich stimme dem ausdrücklich zu.

Aus dieser Perspektive: 

Diese Meldungen erleichtern das Lesen und Durchlaufen des Codes, da sie sowohl der Dokumentation als auch der Fehlerberichterstattung dienen: 

assertEquals( "objects should be identical", expected, actual );
assertTrue( "flag should have been set", flag );
assertNotNull( "object must not be null", object );

Diese Nachrichten sind nicht so leserfreundlich, da sie über den unerwarteten Zustand sprechen:

assertEquals( "objects aren't identical", expected, actual );
assertTrue( "flag is not set", flag );
assertNotNull( "object is null", object );
2
Mohd Farid

Stimmen Sie mir auch ab (wie Jon), aber das einzige Mal, dass ich eine solche Nachricht (bei assert equals) verwende, ist, wenn Sie einen einzelnen Test mit einer Matrix von Werten erstellen und eines der Testelemente fehlschlägt: Ich verwende die Nachricht um anzuzeigen, welcher Testfall fehlgeschlagen ist. Ansonsten ist der Text völlig überflüssig.

1
James Hugard

Aus den Javadocs von JUnit:

Stellt fest, dass zwei Objekte gleich sind. Ob Sie sind kein AssertionFailedError wird mit der angegebenen Nachricht geworfen.

Gemäß der API kann die Nachricht sein, was Sie möchten. Ich würde argumentieren, dass die beiden Optionen, die Sie haben, die gleichen und beide überflüssig sind. Der Erfolg oder Misserfolg der Zusicherung liefert bereits alle Informationen, die Sie in der Nachricht angeben.

Daraus folgt für mich, dass Sie entweder nichts haben sollten (es gibt eine Behauptung, die absichtlich keine Zeichenfolge enthält) OR enthalten eine Nachricht mit einer Bedeutung, die über den bereits vorhandenen Wert hinausgeht.

Ich denke, dies ist eine Wiederholung von Jons Antwort, aber zu wortreich, um ein Kommentar zu sein.

1
Instantsoup

Mir gefällt besonders, wie das Spock-Test-Framework Tests anregt, die sich wie eine Geschichte lesen und Tests unter verschiedenen Frameworks ähnlich strukturieren. Ich mache mir keine besonderen Sorgen um die einzelnen Fehlermeldungen, die sehr viel Sinn machen. Ich möchte, dass ich den gesamten Test schnell umhole, sobald ich ihn öffne: 

assertEquals("Cloned and persisted items", mockedTiCount, clonedTis.size());
assertTrue("Belong to new transaction", clonedTis.stream().allMatch(ti -> ti.getTransaction().getId().equals(cloned.getId())));
assertNotEquals("Which has a different ID", t.getId(), cloned.getId());
assertEquals("While the originals are left intact", mockedTiCount, transactionItemRepository.findByTransactionId(t.getId()).size());

Die Entscheidung für viele kleine Tests anstelle von wenigen großen Tests ist auch hier hilfreich, ebenso wie ein übersichtlich strukturierter, hoffentlich wiederverwendbarer Test-Setup-Code.

0
Gregor Petrin

Ich bin damit einverstanden, dass das Bereitstellen einer Nachricht hilfreich ist, und ich gebe immer eine.

Für mich ist es nützlich, eine klare Aussage darüber zu machen, was falsch gelaufen ist - normalerweise mit den Wörtern „sollte“ oder „sollte nicht“.

Zum Beispiel ist "Objekte sind gleich" mehrdeutig - bedeutet das, dass die Objekte gleich sind und deshalb der Test fehlgeschlagen ist? Oder dass Objekte gleich sein sollen, aber nicht? Wenn Sie jedoch sagen: "Objekte sollten gleich sein" oder "Objekte sollten nicht gleich sein", ist es offensichtlich, warum die Behauptung fehlgeschlagen ist.

0
sync

Ich füge keine Nachricht für den Fall ein, den Sie zitieren, es sei denn, ich führe einen Test aus, bei dem ich ein Array ähnlicher Testwerte habe, die ich in einer Schleife durchführe und genau feststellen möchte, welcher der Tests fehlgeschlagen ist. Dann füge ich eine Nachricht hinzu, um mir zu sagen, welche.

0
duffymo