Sehen Sie, welche API-Testlösung im GigaOm Radar Report am besten abgeschnitten hat. Holen Sie sich Ihren kostenlosen Analystenbericht >>

Sehen Sie, welche API-Testlösung im GigaOm Radar Report am besten abgeschnitten hat. Holen Sie sich Ihren kostenlosen Analystenbericht >>
Zum Abschnitt springen
Das Schreiben von parametrisiertem Testcode kann eine Menge Arbeit sein, da für jeden Test eine Menge korrekt geschriebener Code erforderlich ist. Glücklicherweise erfahren Sie hier, wie Sie Parasoft Jtest verwenden können, um Ihre parametrisierten Tests automatisch zu generieren, ohne Boilerplate-Codes schreiben zu müssen.
Zum Abschnitt springen
Zum Abschnitt springen
Parametrisierte Tests sind eine gute Möglichkeit, mehrere Testfälle zu definieren und auszuführen, wobei der einzige Unterschied zwischen ihnen die Daten sind. Hier sehen wir uns drei verschiedene Frameworks an, die üblicherweise bei JUnit-Tests verwendet werden.
Beim Schreiben von Komponententests werden üblicherweise Methodeneingabeparameter und erwartete Ergebnisse in der Testmethode selbst initialisiert. In einigen Fällen reicht es aus, einen kleinen Satz von Eingaben zu verwenden. Es gibt jedoch Fälle, in denen wir eine große Anzahl von Werten verwenden müssen, um alle Funktionen in unserem Code zu überprüfen. Parametrisierte Tests sind eine gute Möglichkeit, mehrere Testfälle zu definieren und auszuführen, wobei der einzige Unterschied zwischen ihnen die Daten sind. Sie können das Codeverhalten für eine Vielzahl von Werten, einschließlich Grenzfällen, validieren. Parametrisierungstests können die Codeabdeckung erhöhen und die Sicherheit bieten, dass der Code wie erwartet funktioniert.
Es gibt eine Reihe guter Parametrisierungs-Frameworks für Java. In diesem Artikel werden drei verschiedene Frameworks betrachtet, die üblicherweise bei JUnit-Tests verwendet werden, mit einem Vergleich zwischen ihnen und Beispielen für die Struktur der Tests. Schließlich werden wir untersuchen, wie die Erstellung parametrisierter Tests vereinfacht und beschleunigt werden kann.
Vergleichen wir die drei gängigsten Frameworks: JUnit 3, JunitParams und JUnit 4. Jedes JUnit-Parametrisierungsframework hat seine eigenen Stärken und Schwächen.
Vorteile:
Nachteile:
Vorteile:
Nachteile:
Vorteile:
Nachteile:
Angenommen, wir haben eine Methode, mit der Kreditanträge für eine Bank verarbeitet werden. Möglicherweise schreiben wir einen Komponententest, der den Betrag der Kreditanfrage, den Anzahlungsbetrag und andere Werte angibt. Wir würden dann Zusicherungen erstellen, die die Antwort bestätigen - das Darlehen kann genehmigt oder abgelehnt werden, und in der Antwort können die Bedingungen des Darlehens angegeben werden.
Beispielsweise:
public LoanResponse requestLoan (float creditAmount, float downPayment, float availableFunds) {LoanResponse response = new LoanResponse (); response.setApproved (true); if (availableFunds <downPayment) {response.setApproved (false); response.setMessage ("error.insufficient.funds.for.down.payment"); Antwort zurückgeben; } if (Anzahlung / DarlehenAmount <0.1) {response.setApproved (false); response.setMessage ("error.insufficient.down.payment"); } return response; }}
parametrized_test_example_1.java
@Test public void testRequestLoan () löst Throwable aus {// Given LoanProcessor underTest = new LoanProcessor (); // Wenn LoanResponse result = underTest.requestLoan (1000f, 200f, 250f); // Dann assertNotNull (Ergebnis); assertTrue (result.isApproved ()); assertNull (result.getMessage ()); }}
Um sicherzustellen, dass unsere Darlehen anfordern() Methode wird gründlich getestet, wir müssen mit einer Vielzahl von Anzahlungen, angeforderten Darlehensbeträgen und verfügbaren Mitteln testen. Testen wir zum Beispiel eine Kreditanfrage in Höhe von 1 Million US-Dollar ohne Anzahlung, die abgelehnt werden sollte. Wir könnten den vorhandenen Test einfach mit unterschiedlichen Werten duplizieren, aber da die Testlogik dieselbe wäre, ist es effizienter, den Test stattdessen zu parametrisieren.
Wir werden den angeforderten Darlehensbetrag, die Anzahlung und die verfügbaren Mittel sowie die erwarteten Ergebnisse parametrisieren: ob das Darlehen genehmigt wurde und die Nachricht nach der Validierung zurückgegeben wird. Jeder Satz von Anforderungsdaten wird zusammen mit den erwarteten Ergebnissen zu einem eigenen Testfall.
Beginnen wir mit einem parametrisierten Junit 4-Beispiel. Um einen parametrisierten Test zu erstellen, müssen wir zuerst die Variablen für den Test definieren. Wir müssen auch einen Konstruktor einbinden, um sie zu initialisieren:
@RunWith (Parameterized.class) öffentliche Klasse LoanProcessorParameterizedTest {float creditAmount; float downPayment; float availableFunds; Boolescher ExpectApproved; String expectedMessage; public LoanProcessorParameterizedTest (float creditAmount, float downPayment, float availableFunds, boolescher ExpectApproved, String expectedMessage) {this.loanAmount = creditAmount; this.downPayment = downPayment; this.availableFunds = availableFunds; this.expectApproved = expectedApproved; this.expectedMessage = expectedMessage; } // ...}
parametrized_test_example_3.java
Veranstaltet von GitHub
Hier sehen wir, dass der Test das verwendet @ RunWith Anmerkung, um anzugeben, dass der Test mit dem Junit4-parametrisierten Läufer ausgeführt wird. Dieser Läufer muss nach einer Methode suchen, die den Wertesatz für den Test bereitstellt (mit Anmerkungen versehen) @ Parameter), initialisieren Sie den Test ordnungsgemäß und führen Sie die Tests mit mehreren Zeilen aus.
Beachten Sie, dass jeder Parameter als Feld in der Testklasse definiert ist und der Konstruktor diese Werte initialisiert (Sie können Werte auch mit dem in die Felder einfügen @Parameter Anmerkung, wenn Sie keinen Konstruktor erstellen möchten). Für jede Zeile im Wertesatz wird die Parametriert Der Läufer instanziiert die Testklasse und führt jeden Test in der Klasse aus.
Fügen wir eine Methode hinzu, die die Parameter für die bereitstellt Parametriert Läufer:
@Parameters (name = "Führen Sie {index} aus: creditAmount = {0}, downPayment = {1}, availableFunds = {2}, expectedApproved = {3}, expectedMessage = {4}") public static Iterable data () löst Throwable aus {return Arrays.asList (neues Objekt [] [] {{1000.0f, 200.0f, 250.0f, true, null}}); }}
parametrized_test_example_4.java
Veranstaltet von GitHub
Die Wertesätze werden als erstellt Liste of Betreff Arrays von der Daten() Methode, die mit kommentiert wird @ Parameter. Beachten Sie, dass @ Parameter Legt den Namen des Tests mithilfe von Platzhaltern fest, die beim Ausführen des Tests ersetzt werden. Dies macht es einfacher, Werte in Testergebnissen zu sehen, wie wir später sehen werden. Derzeit gibt es nur eine Datenzeile, in der ein Fall getestet wird, in dem das Darlehen genehmigt werden sollte. Wir können weitere Zeilen hinzufügen, um die Abdeckung der zu testenden Methode zu erhöhen.
@Parameters (name = "Führen Sie {index} aus: creditAmount = {0}, downPayment = {1}, availableFunds = {2}, expectedApproved = {3}, expectedMessage = {4}") public static Iterable data () löst Throwable aus {return Arrays.asList (neues Objekt [] [] {{1000.0f, 200.0f, 250.0f, true, null}, {1000.0f, 50.0f, 250.0f, false, "error.insufficient. down.payment "}, {1000.0f, 200.0f, 150.0f, false," error.insufficient.funds.for.down.payment "}}); }}
parametrized_test_example_5.java
Veranstaltet von GitHub
Hier haben wir einen Testfall, in dem das Darlehen genehmigt werden würde, und zwei Fälle, in denen es aus unterschiedlichen Gründen nicht genehmigt werden sollte. Möglicherweise möchten wir Zeilen hinzufügen, in denen Null- oder negative Werte verwendet werden, sowie Randbedingungen testen.
Wir sind jetzt bereit, die Testmethode zu erstellen:
@Test public void testRequestLoan () löst Throwable aus {// Given LoanProcessor underTest = new LoanProcessor (); // Wenn LoanResponse result = underTest.requestLoan (creditAmount, downPayment, availableFunds); // Dann assertNotNull (Ergebnis); assertEquals (expectedApproved, result.isApproved ()); assertEquals (expectedMessage, result.getMessage ()); }}
parametrized_test_example_6.java
Veranstaltet von GitHub
Hier verweisen wir beim Aufrufen von auf die Felder Darlehen anfordern() Methode und Validierung der Ergebnisse.
Die JunitParams-Bibliothek vereinfacht die parametrisierte Testsyntax, indem Parameter direkt an die Testmethode übergeben werden können. Die Parameterwerte werden von einer separaten Methode bereitgestellt, auf deren Namen in der verwiesen wird @ Parameter Anmerkung.
@RunWith (JUnitParamsRunner.class) öffentliche Klasse LoanProcessorParameterizedTest2 {@Test @Parameters (method = "testRequestLoan_Parameters") public void testRequestLoan ("nicht verwendet") privates statisches Objekt [] [] testRequestLoan_Parameters () löst Throwable {// Parameter aus: creditAmount = {0}, downPayment = {1}, availableFunds = {2}, expectedApproved = {3}, expectedMessage = {4 } neues Objekt zurückgeben [] [] {{1000.0f, 200.0f, 250.0f, true, null}, {1000.0f, 50.0f, 250.0f, false, "error.insufficient.down.payment"}, {1000.0f , 200.0f, 150.0f, false, "error.insufficient.funds.for.down.payment"}}; }}
parametrized_test_example_7.java
Veranstaltet von GitHub
JunitParams bietet den zusätzlichen Vorteil, dass die Verwendung von CSV-Dateien zur Bereitstellung von Werten zusätzlich zur Bereitstellung der Werte im Code unterstützt wird. Dadurch kann der Test von den zu aktualisierenden Daten und Datenwerten entkoppelt werden, ohne den Code zu aktualisieren.
JUnit 5 behebt einige der Einschränkungen und Mängel von JUnit 4. Wie JunitParams vereinfacht auch Junit 5 die Syntax parametrisierter Tests. Die wichtigsten Änderungen in der Syntax sind:
Das Definieren des gleichen Beispiels in Junit 5 würde folgendermaßen aussehen:
öffentliche Klasse LoanProcessorParameterizedTest {@ParameterizedTest (name = "Run {index}: creditAmount = {0}, downPayment = {1}, availableFunds = {2}, expectedApproved = {3}, expectedMessage = {4}") @MethodSource (" testRequestLoan_Parameters ") public void testRequestLoan (Float-DarlehenAmount, Float-DownPayment, Float AvailableFunds, Boolean ExpectApproved, String ExpectedMessage) löst Throwable {...} static Stream aus testRequestLoan_Parameters () löst Throwable {return Stream.of (Argumente.of (1000.0f, 200.0f, 250.0f, true, null), Argumente.of (1000.0f, 50.0f, 250.0f, false, "error.insufficient.down) aus .payment "), Arguments.of (1000.0f, 200.0f, 150.0f, false," error.insufficient.funds.for.down.payment ")); }}
parametrized_test_example_8.java
Veranstaltet von GitHub
Wie man sich vorstellen kann, kann das Schreiben des oben parametrisierten Tests ein wenig Arbeit sein. Für jedes parametrisierte Test-Framework gibt es ein bisschen Boilerplate-Code, der korrekt geschrieben werden muss. Es kann schwierig sein, sich an die richtige Struktur zu erinnern, und das Schreiben dauert einige Zeit. Um dies viel einfacher zu machen, können Sie verwenden Parasoft Jtest automatisch parametrisierte Tests wie die oben beschriebenen zu generieren. Wählen Sie dazu einfach die Methode aus, für die Sie einen Test generieren möchten (in Eclipse oder IntelliJ):
Der Test wird unter Verwendung von Standardwerten und Zusicherungen generiert. Anschließend können Sie den Test mit realen Eingabewerten und Zusicherungen konfigurieren und der data () -Methode weitere Datenzeilen hinzufügen.
Parasoft Jtest kann parametrisierte Tests direkt in Eclipse und IntelliJ ausführen.
Die JUnit-Ansicht in Eclipse
Beachten Sie, dass der Name jedes Tests, wie gezeigt, Eingabewerte aus dem Datensatz und erwartete Ergebniswerte enthält. Dies kann das Debuggen des Tests erheblich vereinfachen, wenn er fehlschlägt, da die Eingabeparameter und erwarteten Ausgaben für jeden Fall angezeigt werden.
Sie können auch die Aktion Alle ausführen von Parasoft Jtest verwenden:
Die Flow Tree-Ansicht in Parasoft Jtest
Es analysiert den Testablauf und liefert detaillierte Informationen zum vorherigen Testlauf. Auf diese Weise können Sie sehen, was im Test passiert ist, ohne den Test mit Haltepunkten oder Debugging-Anweisungen erneut ausführen zu müssen. Beispielsweise können Sie parametrisierte Werte in der Variablenansicht anzeigen:
Die Variablenansicht in Parasoft Jtest
Jedes der drei Frameworks, die wir überprüft haben, ist eine gute Wahl und funktioniert gut. Bei Verwendung von JUnit 4 bevorzuge ich JunitParams gegenüber dem integrierten parametrisierten Framework von JUnit 4, da die Testklassen sauberer gestaltet sind und mehrere Testmethoden in derselben Klasse definiert werden können. Wenn Sie jedoch JUnit 5 verwenden, würde ich das integrierte JUnit 5-Framework empfehlen, da es die Mängel in JUnit 4 behebt und keine zusätzlichen Bibliotheken erfordert. Benutze ich auch gerne Einheitentests von Parasoft Funktionen, um das Erstellen, Ausführen und Debuggen parametrisierter Tests effizienter zu gestalten.
Erfahren Sie, wie Sie mit Parasoft Jtest Ihre Java-Codequalität und Teamproduktivität verbessern können.