JUnit ist ein Open-Source-Unit-Testing-Framework eines Drittanbieters. Das Projekt wurde Ende 1995 von Kent Beck und Erich Gamma gestartet. Es stieß schnell auf Interesse in der Community von Entwicklern, die sich insbesondere mit testgetriebener Entwicklung befassen. JUnit wurde ursprünglich in Smalltalk eingeführt, später jedoch auf Java portiert, das dies schnell als De-facto-Standard für Komponententests aufnahm. Die Popularität von JUnit wuchs in einem Ausmaß, dass ein generisches xUnit-Framework entwickelt wurde, in dem der Buchstabe „x“ wird durch den Anfangsbuchstaben der Sprache ersetzt, z. B. JUnit für Java, RUnit für Ruby usw. Dieser Artikel bietet einen Überblick über dieses Framework, wie es vom De-facto-Standard für Java-Einheitentests verwendet wird.
Testübersicht
Das Testen ist eine wichtige Phase im Lebenszyklus einer Anwendungsentwicklung. Der Hauptzweck des Testens besteht darin, ein Programm anhand der erforderlichen Spezifikationen zu evaluieren. Ziel ist es, bestimmte Testfälle zu erstellen, die Fehler, Lücken, Diskrepanzen oder unerwartete Ergebnisse so weit wie möglich aufdecken. Dieses einfache Konzept ist mit einigen ausgefeilten Prozessen verbunden. Aber um es kurz zu machen, es geschieht auf drei Ebenen. Wenn das Testen auf sehr granularer oder individueller Komponentenebene durchgeführt wird, wird es als Einheitentest bezeichnet; Wenn sie kombiniert werden, um die Schnittstellen zwischen Komponenten anhand eines Softwaredesigns zu überprüfen, wird dies als Integrationstest bezeichnet; und schließlich, wenn das komplette System integriert ist und Tests durchgeführt werden, um sicherzustellen, dass das System als Ganzes die spezifizierten Anforderungen erfüllt, wird dies als Systemtest bezeichnet .
Komponententests
Kurz gesagt, die Durchführung eines Komponententests ist eine Möglichkeit, das Verhalten einer bestimmten Codeeinheit zu untersuchen. In Java eine Codeeinheit kann je nach Kontext eine Methode oder eine Klasse oder sogar ein Modul bedeuten. Wenn es sich beispielsweise um eine Methode handelt, liegt der Schwerpunkt des Tests auf der Bewertung der richtigen Objektreferenz, die zum Aufrufen der Methode zulässig ist, des Parametertyps und der zulässigen Werte, der primitiven Wertebereiche, des Rückgabetyps und -werts usw. Die Idee ist, die Methode zu grillen, damit sie robust genug gemacht werden kann, um ihr Problem elegant zu handhaben und diejenigen, die außerhalb ihres Bereichs liegen, von der Erfüllung ihres Vertrags abzuhalten.
Unit-Tests bilden daher den Grundbaustein jeder Programmevaluation. Tatsächlich führt jeder Programmierer beim Schreiben von Code eine Art Komponententest durch, um das Ergebnis des Codes mit einigen Dummy-Daten/Fällen zu überprüfen. Unit-Tests sind somit ein formaler Status, der dieser isolierten Sammlung von Tests verliehen wird. Es ist äußerst wichtig, dass ein Code die Härte verschiedener Testphasen durchläuft. Das Unit-Testing ist neben seiner Bedeutung auch sehr alltäglich. Leute wie Kent Beck und Erich Gamma dachten daran, einen Rahmen dafür zu schaffen, damit Programmierer eine strukturierte Umgebung erhalten und viele dieser Aufgaben automatisieren können. Dafür ist schließlich ein Framework da. Typischerweise stellt es eine kohärente Programmstruktur bereit, die wiederverwendbar und über Anwendungen hinweg gemeinsam nutzbar ist. Ein Programmierer kann sie in eine bestehende Anwendung integrieren und sie entsprechend seinen spezifischen Anforderungen erweitern.
Ein kurzes Beispiel
Ein einfacher Komponententestcode zum Untersuchen der einzelnen Methode in Temperature Klasse ohne Verwendung des JUnit-Frameworks lautet wie folgt:
package org.mano.unittest.examples; public class Circle { double area(double radius) { returnMath.PI* radius * radius; } }
Lassen Sie uns nun den Code schreiben, um den Bereich zu testen Methode.
package org.mano.unittest.examples; public class CircleTest { public int errCounter= 0; public void testCircleArea() { Circle circle = new Circle(); double area = circle.area(12); if (area < 452 && area > 453) { throw new IllegalStateException("Wrong calculation!: " + area); } } public static void main(String[] args) { TestCircle test = new TestCircle(); try { test.testCircleArea(); } catch (Throwable e) { test.errCounter++; e.printStackTrace(); } if (test.errCounter> 0) { throw new IllegalStateException("There were " + test.errCounter+ " error(s)"); } } }
Dies ist ein rudimentäres Beispiel, gibt Ihnen aber eine Vorstellung davon, wie Komponententests ohne die Verwendung eines Frameworks durchgeführt werden können.
JUnit Testing Framework
Die Verwendung des JUnit-Frameworks für Unit-Tests hat mehrere Vorteile. Es bietet zahlreiche Anmerkungen, die das Schreiben und Ausführen von Testcodes in Java erleichtern:
- In erster Linie trennt es die Belange des Komponententests vom eigentlichen Projektcode, indem es einem ermöglicht, eine Testklasseninstanz und Klassenlader für jeden Komponententest zu erstellen. Diese „immunisieren“ den bestehenden Code vor unnötigen Nebeneffekten des Testens.
- Die von JUnit bereitgestellten Anmerkungen – wie @Before, @After, @BeforeClass, @AfterClass – haben Methoden sowohl für die Ressourceninitialisierung als auch für die Ressourcenrückgewinnung.
- Es gibt eine Vielzahl von Assert-Methoden, um das Ergebnis eines Tests zu überprüfen.
- Im Laufe der Jahre wurde JUnit so beliebt, dass zahlreiche Java-Tools wie Ant und Maven; und beliebte IDEs wie Eclipse , NetBeans , IntelliJ IDEE , und dergleichen, kommt mit eingebauter Integration von JUnit.
Um das JUnit-Testframework in einem Java-Projekt zu verwenden, muss dem Klassenpfad des Projekts eine JUnit-JAR-Datei hinzugefügt werden. Dies ist explizit erforderlich, wenn die IDE nicht mit der JUnit-Bibliothek integriert ist. Der Prozess ist einfach. Laden Sie die JAR-Datei herunter und fügen Sie sie dem Klassenpfad des Projekts hinzu.
Hier sind einige wichtige Links zum JUnit-Framework.
- Offizielle Website von JUnit
- JUnit-Java-API
- JUnit-Benutzerhandbuch
- JUnit-Quellcode in GitHub
Im Gegensatz zu JUnit 4 und seinen Vorgängern brachte JUnit 5 einige wesentliche Änderungen mit sich. Abgesehen von vielen neuen hinzugefügten Funktionen – wie Lambda-Unterstützung, neuen Anmerkungen und Parameterinjektion für Testmethoden – wurde die Kernarchitektur erheblich modifiziert. JUnit 5 ist jetzt eine zusammengesetzte Architektur aus drei verschiedenen Modulen:JUnit Jupiter, JUnit Vintage und JUnit Platform. Um die Feinheiten der Änderungen müssen sich die Testfall-Entwickler jedoch nicht kümmern. Die Änderungen bedeuten in erster Linie eine bessere Toolunterstützung, Konsistenz und sauberere APIs. Vor allem ist es absolut abwärtskompatibel mit JUnit 4. Also auch da keine Sorge. Weitere Informationen finden Sie im JUnit 5-Benutzerhandbuch.
Ein kurzes Beispiel
Hier ist ein sehr einfaches Beispiel, um einen Eindruck davon zu bekommen, wie Komponententests mit dem JUnit-Framework durchgeführt werden können. Wir verwenden den Mitarbeiter -Klasse für den Komponententest und erstellen Sie eine Testklasse, um eine Vorstellung von ihrer Funktionsweise zu vermitteln. Das Beispiel ist rudimentär in dem Umfang, ein „Hello World“-Programm zu schreiben. Reale Testfälle oder sogar ein anständiges Beispiel für Komponententests erfordern eine Menge Code. Vielleicht versuchen wir das in einem anderen Artikel.
package org.mano.unittest.examples; public class Employee { private final String name; private final double basicPay; public Employee(String name, double basicPay) { this.name=name; this.basicPay=basicPay; } public String getName() { return name; } public double getBasicPay() { return basicPay; } } package org.mano.unittest.examples; import org.junit.Test; import static org.junit.Assert.*; public class EmployeeTest { @Test public void constructorInitTest(){ Employee emp=new Employee("Odin", 2300); assertEquals("Odin", emp.getName()); assertEquals(2300, emp.getBasicPay(), 0.001); } } package org.mano.unittest.examples; public class EmployeeTestMain { public static void main(String[] args){ EmployeeTest et=new EmployeeTest(); et.constructorInitTest(); } }
Beachten Sie, dass die Employee-Klasse unveränderlich ist und nur zwei Felder vom Konstruktor festgelegt werden. Da nur die Contructor-Methode einen Test wert ist, werden wir nur diese testen.
Die Testklasse heißt EmployeeTest nach Konvention. Die Anmerkung @Test ermöglicht JUnit, eine Methode als Testmethode festzulegen. Es gibt eine Vielzahl von Assert-Methoden im Assert Klasse. Hier haben wir nur assertEquals verwendet .
Es gibt viele Möglichkeiten, einen in JUnit geschriebenen Test auszuführen. Normalerweise wird nach der Ausführung der Testfälle eine Zusammenfassung gedruckt. Sie kann jedoch variieren, je nachdem, wie der Test durchgeführt wird. Es kann über IDEs wie Eclipse oder IntelliJ oder Tools wie Maven, Gradle usw. ausgeführt werden. Manchmal erhalten Sie nach dem Test nur die Information, dass er entweder nicht bestanden oder bestanden wurde.
Schlussfolgerung
Es gibt mehrere andere Frameworks für Unit-Tests. JUnit ist ein beliebtes Unit-Testing-Framework in der Java-Community. Das Testen als System-Engineering-Phase ist mit viel mehr Prozessen verbunden. Unit-Tests sind nur ein Teil davon, und interessanterweise können viele Spieltests, die vom Entwickler durchgeführt werden, als Unit-Tests bezeichnet werden. JUnit als Test-Framework fügt ihm einen Mehrwert hinzu. Die von JUnit bereitgestellten Anmerkungen und APIs automatisieren viele Aufgaben und machen das Leben für die Unit-Test-Entwickler viel einfacher.