Vielleicht ist meine Frage eine Neulingsfrage, aber ich kann die Umstände, unter denen ich sie verwenden würde, nicht wirklich verstehen junit?
Egal, ob ich einfache oder größere Anwendungen schreibe, ich teste sie mit den System.out
Aussagen und es fällt mir ziemlich leicht.
Warum Testklassen mit JUnit erstellen, unnötige Ordner im Projekt, wenn wir immer noch dieselben Methoden aufrufen müssen, überprüfen, was sie zurückgeben, und dann einen Aufwand haben, alles mit Anmerkungen zu versehen?
Warum nicht eine Klasse schreiben und sofort testen, System.out
aber keine Testklassen erstellen?
PS. Ich habe noch nie an großen Projekten gearbeitet, die ich gerade lerne.
Was ist der Zweck?
java
unit-testing
junit
tdd
Artem Moskalev
quelle
quelle
Antworten:
Das ist kein Test, das ist "manuelles Betrachten der Ausgabe" (im Geschäft als LMAO bekannt). Formal ist es bekannt als "manuell nach abnormalen Ausgaben suchen" (LMFAO). (Siehe Anmerkung unten)
Jedes Mal, wenn Sie Code ändern, müssen Sie die App und LMFAO für den gesamten Code ausführen, der von diesen Änderungen betroffen ist. Dies ist selbst bei kleinen Projekten problematisch und fehleranfällig.
Skalieren Sie jetzt bei jeder Codeänderung auf 50.000, 250.000, 1 m LOC oder mehr und LMFAO. Es ist nicht nur unangenehm, es ist auch unmöglich: Sie haben die Kombinationen von Eingaben, Ausgaben, Flags und Bedingungen vergrößert, und es ist schwierig, alle möglichen Zweige auszuüben.
Schlimmer noch, LMFAO könnte bedeuten, Seiten für Seiten der Web-App zu besuchen, Berichte auszuführen, über Millionen von Protokollzeilen in Dutzenden von Dateien und Maschinen zu stöbern, generierte und zugestellte E-Mails zu lesen, Textnachrichten zu überprüfen, den Weg eines Roboters zu überprüfen und eine Flasche zu füllen Soda, Sammeln von Daten aus hundert Webdiensten, Überprüfen des Prüfpfads einer Finanztransaktion ... Sie haben die Idee. "Ausgabe" bedeutet nicht einige Textzeilen, "Ausgabe" bedeutet aggregiertes Systemverhalten.
Schließlich definieren Einheiten- und Verhaltenstests das Systemverhalten. Tests können von einem Continuous Integration Server ausgeführt und auf Richtigkeit überprüft werden. Sicher, das kann auch so sein
System.out
, aber der CI-Server wird nicht wissen, ob einer von ihnen falsch ist - und wenn ja , handelt es sich um Komponententests, und Sie können auch ein Framework verwenden.Egal wie gut wir uns fühlen, Menschen sind keine guten Unit-Test-Frameworks oder CI-Server.
Hinweis: LMAO ist die Prüfung, aber in einem sehr begrenzten Sinn. Es ist nicht sinnvoll in einem gesamten Projekt oder als Teil eines Prozesses wiederholbar. Es ist vergleichbar mit der schrittweisen Entwicklung in einer REPL, aber niemals der Formalisierung dieser inkrementellen Tests.
quelle
Wir schreiben Tests, um die Richtigkeit des Verhaltens eines Programms zu überprüfen.
Das Überprüfen der Richtigkeit des Verhaltens eines Programms durch Überprüfen des Inhalts von Ausgabeanweisungen mit Ihren Augen ist ein manueller oder genauer gesagt ein visueller Prozess.
Das könnte man argumentieren
Zunächst einmal ist es großartig, dass Sie daran interessiert sind, ob der Code richtig funktioniert oder nicht. Das ist gut. Du bist der Kurve voraus! Leider gibt es Probleme mit diesem Ansatz.
Das erste Problem bei der Sichtprüfung besteht darin, dass Sie einen schweren Schweißunfall haben und nicht mehr in der Lage sind, die Richtigkeit Ihres Codes erneut zu überprüfen.
Das zweite Problem ist, dass das verwendete Augenpaar eng mit dem Gehirn des Augenbesitzers verbunden ist. Wenn der Autor des Codes auch die Augen besitzt, die für den visuellen Inspektionsprozess verwendet werden, hängt der Prozess der Überprüfung der Korrektheit vom Wissen über das Programm ab, das im Gehirn des visuellen Inspektors verinnerlicht ist.
Es ist schwierig für ein neues Augenpaar, die Richtigkeit des Codes zu überprüfen, nur weil sie nicht mit dem Gehirn des ursprünglichen Codierers zusammenarbeiten. Der Besitzer des zweiten Augenpaares muss sich mit dem ursprünglichen Autor des Codes unterhalten , um den betreffenden Code vollständig zu verstehen. Konversation als Mittel zum Wissensaustausch ist notorisch unzuverlässig. Ein Punkt, der umstritten ist, wenn der Original-Codierer für die neuen Paaraugen nicht verfügbar ist. In diesem Fall muss das neue Augenpaar den Originalcode lesen.
Das Lesen des Codes anderer Personen, der nicht durch Unit-Tests abgedeckt ist, ist schwieriger als das Lesen von Code, dem Unit-Tests zugeordnet sind. Im besten Fall ist das Lesen des Codes anderer Leute eine schwierige Aufgabe, im schlimmsten Fall ist dies die schwierigste Aufgabe in der Softwareentwicklung. Es gibt einen Grund, warum Arbeitgeber bei der Werbung für offene Stellen betonen, dass ein Projekt auf der grünen Wiese (oder brandneu) ist. Das Schreiben von Code von Grund auf ist einfacher als das Ändern von vorhandenem Code und lässt den ausgeschriebenen Job für potenzielle Mitarbeiter attraktiver erscheinen.
Beim Unit-Test teilen wir den Code in seine Bestandteile auf. Für jede Komponente legen wir dann unseren Stand fest, wie sich das Programm verhalten soll . Jeder Komponententest erzählt eine Geschichte darüber, wie sich dieser Teil des Programms in einem bestimmten Szenario verhalten sollte. Jeder Komponententest ist wie eine Klausel in einem Vertrag, die beschreibt, was aus Sicht des Kundencodes geschehen soll.
Dies bedeutet dann, dass ein neues Augenpaar zwei Stränge lebendiger und genauer Dokumentation des betreffenden Codes enthält.
Zuerst haben sie den Code selbst, die Implementierung, wie der Code gemacht wurde ; Zweitens haben sie das gesamte Wissen, das der ursprüngliche Codierer in einer Reihe formaler Aussagen beschrieben hat, die die Geschichte darüber erzählen, wie sich dieser Code verhalten soll.
Unit-Tests erfassen und beschreiben formal das Wissen, das der ursprüngliche Autor bei der Implementierung der Klasse besaß. Sie enthalten eine Beschreibung des Verhaltens dieser Klasse bei Verwendung durch einen Client.
Sie stellen zu Recht die Nützlichkeit dieses Vorgangs in Frage, da es möglich ist, nutzlose Komponententests zu schreiben, die nicht den gesamten fraglichen Code abdecken, veraltet oder veraltet sind usw. Wie stellen wir sicher, dass Unit-Tests den Prozess eines sachkundigen, gewissenhaften Autors, der die Ausgabeanweisungen seines Codes zur Laufzeit visuell überprüft, nicht nur nachahmen, sondern auch verbessern? Schreiben Sie zuerst den Komponententest und dann den Code, um diesen Test zu bestehen. Wenn Sie fertig sind, lassen Sie die Computer die Tests ausführen. Sie sind schnell und eignen sich hervorragend für sich wiederholende Aufgaben. Sie sind ideal für den Job geeignet.
Stellen Sie die Testqualität sicher, indem Sie sie jedes Mal überprüfen, wenn Sie den Code berühren, den sie testen, und die Tests für jeden Build ausführen. Wenn ein Test fehlschlägt, beheben Sie ihn sofort.
Wir automatisieren den Prozess der Ausführung von Tests so, dass sie jedes Mal ausgeführt werden, wenn wir ein Projekt erstellen. Wir automatisieren auch die Erstellung von Codeabdeckungsberichten, in denen angegeben ist, wie viel Prozent des Codes von Tests abgedeckt und ausgeführt werden. Wir streben hohe Prozentsätze an. Einige Unternehmen verhindern, dass Codeänderungen in die Quellcodeverwaltung eingecheckt werden, wenn nicht genügend Komponententests geschrieben wurden, um Änderungen im Verhalten des Codes zu beschreiben. In der Regel überprüft ein zweites Augenpaar die Codeänderungen in Verbindung mit dem Autor der Änderungen. Der Prüfer wird die Änderungen durchgehen, um sicherzustellen, dass die Änderungen verständlich sind und durch Tests ausreichend abgedeckt werden. Der Überprüfungsprozess ist also manuell. Wenn die Tests (Einheiten- und Integrationstests und möglicherweise Benutzerakzeptanztests) diesen manuellen Überprüfungsprozess bestehen, werden sie Teil des automatischen Erstellungsprozesses. Diese werden jedes Mal ausgeführt, wenn eine Änderung eingecheckt wird. A.kontinuierliche Integration Der Server führt diese Aufgabe im Rahmen des Erstellungsprozesses aus.
Tests, die automatisch ausgeführt werden, behalten die Integrität des Codeverhaltens bei und verhindern , dass zukünftige Änderungen an der Codebasis den Code beschädigen .
Durch das Bereitstellen von Tests können Sie Code aggressiv neu faktorisieren, da Sie große Codeverbesserungen sicher durchführen können, wenn Sie wissen, dass Ihre Änderungen vorhandene Tests nicht beschädigen.
Test Driven Development hat eine Einschränkung : Sie müssen Code schreiben, um ihn testbar zu machen. Dies beinhaltet das Codieren in Schnittstellen und die Verwendung von Techniken wie Dependency Injection, um kollaborierende Objekte zu instanziieren. Schauen Sie sich die Arbeit von Kent Beck an , der TDD sehr gut beschreibt. Suchen Sie nach Codierung für Schnittstellen und studieren SieDesignmuster
quelle
Wenn Sie mit System.out testen, testen Sie nur eine kleine Teilmenge möglicher Anwendungsfälle. Dies ist nicht sehr gründlich, wenn Sie mit Systemen arbeiten, die nahezu unendlich viele verschiedene Eingaben akzeptieren können.
Unit-Tests ermöglichen es Ihnen, schnell Tests für Ihre Anwendung durchzuführen, indem Sie einen sehr großen und vielfältigen Satz verschiedener Dateneingaben verwenden. Darüber hinaus berücksichtigen die besten Komponententests auch Grenzfälle, z. B. die Dateneingaben, die direkt am Rand dessen liegen, was als gültig angesehen wird.
Es kann Wochen dauern, bis ein Mensch all diese verschiedenen Eingaben getestet hat, während es für eine Maschine Minuten dauern kann.
Stellen Sie sich das so vor: Sie "testen" auch nicht etwas, das statisch ist. Ihre Anwendung wird höchstwahrscheinlich ständig geändert. Daher sind diese Komponententests so konzipiert, dass sie an verschiedenen Punkten im Kompilierungs- oder Bereitstellungszyklus ausgeführt werden. Der vielleicht größte Vorteil ist folgender:
Wenn Sie etwas in Ihrem Code beschädigen, wissen Sie es sofort , nicht nach der Bereitstellung, nicht, wenn ein QS-Tester einen Fehler entdeckt, nicht, wenn Ihre Clients abgebrochen haben. Sie haben auch eine bessere Chance, den Fehler sofort zu beheben , da klar ist, dass das, was den Teil des fraglichen Codes gebrochen hat, höchstwahrscheinlich seit Ihrer letzten Kompilierung passiert ist. Dadurch wird der zur Behebung des Problems erforderliche Ermittlungsaufwand erheblich reduziert.
quelle
Ich habe ein anderes System hinzugefügt. Out kann NICHT:
Machen Sie jeden Testfall unabhängig (es ist wichtig)
JUnit kann es: Jedes Mal, wenn eine neue Testfallinstanz erstellt und
@Before
aufgerufen wird.Trennen Sie den Testcode von der Quelle
JUnit kann es schaffen.
Integration mit CI
JUnit kann das mit Ant und Maven.
Ordnen und kombinieren Sie Testfälle einfach
JUnit kann
@Ignore
Suite ausführen und testen.Einfach zu überprüfendes Ergebnis
JUnit bietet viele Assert-Methoden (
assertEquals
,assertSame
...)Mit Mock und Stub können Sie sich auf das Testmodul konzentrieren.
JUnit kann Folgendes tun: Mit Mock und Stub können Sie das richtige Gerät einrichten und sich auf die Logik des Testmoduls konzentrieren.
quelle
Unit-Tests stellen sicher, dass der Code wie vorgesehen funktioniert. Sie sind auch sehr hilfreich, um sicherzustellen, dass der Code weiterhin wie vorgesehen funktioniert, falls Sie ihn später ändern müssen, um neue Funktionen zur Behebung eines Fehlers zu erstellen. Durch eine hohe Testabdeckung Ihres Codes können Sie Funktionen weiterentwickeln, ohne viele manuelle Tests durchführen zu müssen.
Ihr manueller Ansatz
System.out
ist gut, aber nicht der beste. Dies ist ein einmaliger Test, den Sie durchführen. In der realen Welt ändern sich die Anforderungen ständig und meistens nehmen Sie viele Änderungen an vorhandenen Funktionen und Klassen vor. Also ... nicht jedes Mal, wenn Sie den bereits geschriebenen Code testen.Es gibt auch einige erweiterte Funktionen, die in JUnit ähnlich sind
Aussagen behaupten
JUnit bietet Methoden zum Testen auf bestimmte Bedingungen. Diese Methoden beginnen normalerweise mit Asserts und ermöglichen es Ihnen, die Fehlermeldung, das erwartete und das tatsächliche Ergebnis anzugeben
Einige dieser Methoden sind
fail([message])
- Lässt den Test fehlschlagen. Kann verwendet werden, um zu überprüfen, ob ein bestimmter Teil des Codes nicht erreicht wird. Oder um einen fehlgeschlagenen Test zu haben, bevor der Testcode implementiert wird.assertTrue(true)
/assertTrue(false)
- Wird immer wahr / falsch sein. Kann verwendet werden, um ein Testergebnis vorab zu definieren, wenn der Test noch nicht implementiert ist.assertTrue([message,] condition)
- Überprüft, ob der Boolesche Wertcondition
wahr ist.assertEquals([message,] expected, actual)
- Testet, ob zwei Werte gleich sind (gemäß derequals
implementierten Methode, andernfalls unter Verwendung eines==
Referenzvergleichs). Hinweis: Bei Arrays wird die Referenz überprüft und nicht der InhaltassertArrayEquals([message,] expected, actual)
.assertEquals([message,] expected, actual, delta)
- Testet, ob zwei Float- oder Double-Werte in einem bestimmten Abstand voneinander liegen, gesteuert durch dendelta
Wert.assertNull([message,] object)
- Überprüft, ob das Objekt null istund so weiter. Alle Beispiele finden Sie im vollständigen Javadoc .
Suiten
Mit Testsuiten können Sie in gewisser Weise mehrere Testklassen zu einer Einheit kombinieren , sodass Sie alle gleichzeitig ausführen können. Ein einfaches Beispiel, um die Testklassen kombiniert
MyClassTest
undMySecondClassTest
in eine Suite genanntAllTests
:quelle
Der Hauptvorteil von JUnit besteht darin, dass es automatisiert ist und nicht manuell anhand Ihrer Ausdrucke überprüft werden muss. Jeder Test, den Sie schreiben, bleibt bei Ihrem System. Dies bedeutet, dass wenn Sie eine Änderung vornehmen, die unerwartete Nebenwirkungen hat, Ihr Test diese abfängt und fehlschlägt, anstatt dass Sie daran denken müssen, nach jeder Änderung alles manuell zu testen.
quelle
JUnit ist ein Unit-Test-Framework für die Java-Programmiersprache. Es ist wichtig für die testgetriebene Entwicklung und gehört zu einer Familie von Unit-Testing-Frameworks, die zusammen als xUnit bezeichnet werden.
JUnit fördert die Idee "Erst testen, dann codieren", wobei der Schwerpunkt auf der Einrichtung der Testdaten für einen Code liegt, der zuerst getestet und dann implementiert werden kann. Dieser Ansatz ist wie "ein wenig testen, ein wenig codieren, ein wenig testen, ein wenig codieren ...", was die Produktivität des Programmierers und die Stabilität des Programmcodes erhöht, wodurch der Stress des Programmierers und die für das Debuggen aufgewendete Zeit verringert werden.
Funktionen JUnit ist ein Open Source-Framework, das zum Schreiben und Ausführen von Tests verwendet wird.
Bietet Anmerkungen zur Identifizierung der Testmethoden.
Bietet Aussagen zum Testen der erwarteten Ergebnisse.
Bietet Testläufer zum Ausführen von Tests.
Mit JUnit-Tests können Sie Code schneller schreiben, was die Qualität erhöht
JUnit ist elegant einfach. Es ist weniger komplex und benötigt weniger Zeit.
JUnit-Tests können automatisch ausgeführt werden und überprüfen ihre eigenen Ergebnisse und geben sofortiges Feedback. Es ist nicht erforderlich, einen Bericht mit Testergebnissen manuell durchzukämmen.
JUnit-Tests können in Testsuiten mit Testfällen und sogar in anderen Testsuiten organisiert werden.
Junit zeigt den Testfortschritt in einem grünen Balken an, wenn der Test gut läuft, und wird rot, wenn ein Test fehlschlägt.
quelle
Ich habe eine etwas andere Perspektive, warum JUnit benötigt wird.
Sie können tatsächlich alle Testfälle selbst schreiben, dies ist jedoch umständlich. Hier sind die Probleme:
Stattdessen
System.out
können wirif(value1.equals(value2))
0 oder -1 oder eine Fehlermeldung hinzufügen und zurückgeben. In diesem Fall benötigen wir eine "Haupt" -Testklasse, die alle diese Methoden ausführt, die Ergebnisse überprüft und verwaltet, welche Testfälle fehlgeschlagen sind und welche bestanden wurden.Wenn Sie weitere Tests hinzufügen möchten, müssen Sie diese auch zu dieser "Haupt" -Testklasse hinzufügen. Änderungen am vorhandenen Code. Wenn Sie Testfälle aus Testklassen automatisch erkennen möchten, müssen Sie Reflection verwenden.
Alle Ihre Tests und Ihre Hauptklasse zum Ausführen von Tests werden von Eclipse nicht erkannt, und Sie müssen benutzerdefinierte Debug- / Ausführungskonfigurationen schreiben, um diese Tests auszuführen. Sie sehen diese hübschen grün / rot gefärbten Ausgänge jedoch immer noch nicht.
Folgendes macht JUnit:
Es verfügt über
assertXXX()
Methoden, mit denen hilfreiche Fehlermeldungen aus den Bedingungen gedruckt und die Ergebnisse an die Hauptklasse übertragen werden können.Die "Hauptklasse" heißt Runner und wird von JUnit bereitgestellt. Wir müssen also keine schreiben. Und es erkennt die Testmethoden automatisch durch Reflexion. Wenn Sie neue Tests mit hinzufügen
@Test
Anmerkungen diese automatisch erkannt.JUnit verfügt auch über eine Eclipse-Integration und eine Maven / Gradle-Integration, sodass Tests einfach ausgeführt werden können und Sie keine benutzerdefinierten Ausführungskonfigurationen schreiben müssen.
Ich bin kein Experte für JUnit, daher habe ich verstanden, dass dies in Zukunft noch mehr hinzufügen wird.
quelle
Sie können keinen Testfall schreiben, ohne das Testframework zu verwenden, oder Sie müssen Ihren Testrahmen schreiben, um Ihren Testfällen gerecht zu werden. Hier finden Sie einige Informationen zu JUnit Framework. Außerdem können Sie das TestNG-Framework verwenden.
Was ist Junit?
Junit ist ein weit verbreitetes Testframework zusammen mit Java Programming Language. Sie können dieses Automatisierungsframework sowohl für Komponententests als auch für UI-Tests verwenden. Es hilft uns, den Ausführungsfluss unseres Codes mit verschiedenen Anmerkungen zu definieren. Junit basiert auf der Idee, "zuerst zu testen und dann zu codieren", um die Produktivität von Testfällen und die Stabilität des Codes zu steigern.
Wichtige Merkmale von Junit-Tests -
quelle
JUNIT ist die Methode, die normalerweise von Java-Entwicklern akzeptiert wird. Wenn sie ähnliche erwartete Eingaben für die Funktion bereitstellen und entsprechend entscheiden können, dass der geschriebene Code perfekt geschrieben ist, oder wenn der Testfall fehlschlägt, muss möglicherweise auch ein anderer Ansatz implementiert werden. JUNIT beschleunigt die Entwicklung und stellt die 0 Funktionsfehler sicher.
quelle
JUNIT: BEOBACHTEN UND EINSTELLEN
Hier ist meine Perspektive von JUNIT.
JUNIT kann verwendet werden, um
1) ein Systemverhalten zu beobachten, wenn eine neue Einheit in diesem System hinzugefügt wird.
2) Nehmen Sie Anpassungen im System vor, um die "neue" Einheit im System willkommen zu heißen.
Was? Genau.
Wenn Ihr Verwandter Ihr College-Hostelzimmer besucht,
1) geben Sie vor, verantwortungsbewusster zu sein.
2) Sie werden alle Dinge dort aufbewahren, wo sie sein sollten, wie Schuhe im Schuhregal, nicht auf dem Stuhl, Kleidung im Schrank, nicht auf dem Stuhl.
3) Sie werden alle Schmuggelware los.
4) Sie starten cleanUp auf jedem Gerät, das Sie besitzen.
System: Ihr Code
EINHEIT: Neue Funktionalität.
Da das JUNIT-Framework für die JAVA-Sprache verwendet wird, ist JUNIT = JAVA UNIT (möglicherweise).
Angenommen, Sie haben bereits einen gut kugelsicheren Code, aber es ist eine neue Anforderung aufgetreten, und Sie müssen die neue Anforderung in Ihren Code einfügen. Diese neue Anforderung kann Ihren Code für einige Eingaben (Testfall) beschädigen.
Die einfache Möglichkeit, diese Änderung anzupassen, ist das Testen von Einheiten (JUNIT).
Dazu sollten Sie beim Erstellen Ihrer Codebasis mehrere Testfälle für Ihren Code schreiben. Und wenn eine neue Anforderung auftritt, führen Sie einfach alle Testfälle aus, um festzustellen, ob ein Testfall fehlschlägt. Wenn Nein, sind Sie ein BadA ** -Künstler und können den neuen Code bereitstellen.
Wenn einer der Testfälle fehlschlägt, ändern Sie Ihren Code und führen erneut Testfälle aus, bis Sie den grünen Status erhalten.
quelle