Wie schreibe ich einen Unit Test?

135

Ich habe eine Java-Klasse. Wie kann ich es testen ?


In meinem Fall habe ich Klasse macht eine binäre Summe. Es werden zwei byte[]Arrays benötigt, summiert und ein neues binäres Array zurückgegeben.

Tsundoku
quelle
7
Sie können ein Tool wie jUnit verwenden und Testfälle (Testmethoden) für Ihre Java-Klasse schreiben. Rufen Sie dann die jUnit-Tests als Teil des Erstellungsprozesses auf (ant / maven). Die Verwendung von jUnit ist überhaupt nicht schwierig. Der schwierige Teil besteht darin, so viele Testszenarien zu entwickeln, wie Sie sich vorstellen können, damit Sie die Fehler frühzeitig und häufig erkennen.
CoolBeans

Antworten:

132
  1. Definieren Sie die erwartete und gewünschte Ausgabe für einen Normalfall mit korrekter Eingabe.

  2. Implementieren Sie nun den Test, indem Sie eine Klasse deklarieren, sie beliebig benennen (normalerweise so etwas wie TestAddingModule) und die testAdd-Methode hinzufügen (dh wie die folgende):

    • Schreiben Sie eine Methode und fügen Sie darüber die Annotation @Test hinzu.
    • Führen Sie in der Methode Ihre Binärsumme und aus assertEquals(expectedVal,calculatedVal).
    • Testen Sie Ihre Methode, indem Sie sie ausführen (klicken Sie in Eclipse mit der rechten Maustaste und wählen Sie Ausführen als → JUnit-Test).

      //for normal addition 
      @Test
      public void testAdd1Plus1() 
      {
          int x  = 1 ; int y = 1;
          assertEquals(2, myClass.add(x,y));
      }
      
  3. Fügen Sie nach Bedarf weitere Fälle hinzu.

    • Testen Sie, ob Ihre Binärsumme keine unerwartete Ausnahme auslöst, wenn ein ganzzahliger Überlauf vorliegt.
    • Testen Sie, ob Ihre Methode Null-Eingaben ordnungsgemäß verarbeitet (Beispiel unten).

      //if you are using 0 as default for null, make sure your class works in that case.
      @Test
      public void testAdd1Plus1() 
      {
          int y = 1;
          assertEquals(0, myClass.add(null,y));
      }
      
jayunit100
quelle
1. Ist die @ Test-Notation erforderlich? 2. Warum nicht mit assertNotNull auf Null-Eingabe testen? 3. Wo werden die Ergebnisse der Unit-Tests erfasst? Wie werden die Ergebnisse dem Benutzer angezeigt?
user137717
10
Ja, eine @TestNotation ist erforderlich. Dies wird durchgeführt, um dem Unit-Test-Läufer zu signalisieren, dass diese Methode einen Unit-Test darstellt und ausgeführt werden sollte. Methoden, die nicht mit Anmerkungen versehen @Testsind, werden vom Testläufer nicht ausgeführt.
Ali Shah Ahmed
für den zweiten Test - sollte man nicht ein hinzufügen, nullum ynur zu geben y?
Adjit
Vielen Dank! Ich möchte wissen, warum es nicht notwendig ist static, den Modifikator der Testmethode zu ergänzen .
Liang Zhang
103

Ich biete diesen Beitrag sowohl für IntelliJ als auch für Eclipse an .

Finsternis:

Führen Sie die folgenden Schritte aus, um einen Komponententest für Ihr Projekt durchzuführen (ich verwende Eclipse, um diesen Test zu schreiben):

1- Klicken Sie auf Neu -> Java-Projekt.

Projekt erstellen

2- Notieren Sie sich Ihren Projektnamen und klicken Sie auf Fertig stellen.

Projekt erstellen

3- Klicken Sie mit der rechten Maustaste auf Ihr Projekt. Klicken Sie dann auf Neu -> Klasse.

Klasse erstellen

4- Notieren Sie sich Ihren Klassennamen und klicken Sie auf Fertig stellen.

Klasse erstellen

Schließen Sie die Klasse dann folgendermaßen ab:

public class Math {
    int a, b;
    Math(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int add() {
        return a + b;
    }
}

5- Klicken Sie auf Datei -> Neu -> JUnit-Testfall.

Erstellen Sie einen JUnite-Test

6- Überprüfen Sie setUp () und klicken Sie auf Fertig stellen. SetUp () ist der Ort, an dem Sie Ihren Test initialisieren.

Überprüfen Sie SetUp ()

7- Klicken Sie auf OK.

JUnit hinzufügen

8- Hier füge ich einfach 7 und 10 hinzu. Ich erwarte also, dass die Antwort 17 lautet. Schließen Sie Ihre Testklasse wie folgt ab:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MathTest {
    Math math;
    @Before
    public void setUp() throws Exception {
        math = new Math(7, 10);
    }
    @Test
    public void testAdd() {
        Assert.assertEquals(17, math.add());
    }
}

9- Schreiben Sie im Paket-Explorer auf Ihre Testklasse und dann auf Ausführen als -> JUnit-Test.

Führen Sie den JUnit-Test aus

10- Dies ist das Ergebnis des Tests.

Ergebnis des Tests

IntelliJ: Beachten Sie, dass ich für die Screenshots die IntelliJ IDEA Community 2020.1 verwendet habe. Außerdem müssen Sie Ihr jre vor diesen Schritten einrichten. Ich verwende JDK 11.0.4.

1- Klicken Sie mit der rechten Maustaste auf den Hauptordner Ihres Projekt-> Neu -> Verzeichnisses. Sie sollten diesen "Test" nennen. Geben Sie hier die Bildbeschreibung ein 2- Klicken Sie mit der rechten Maustaste auf den Testordner und erstellen Sie das richtige Paket. Ich schlage vor, die gleichen Verpackungsnamen wie die ursprüngliche Klasse zu erstellen. Klicken Sie dann mit der rechten Maustaste auf das Testverzeichnis -> markieren Sie das Verzeichnis als -> Testquellenstamm. Geben Sie hier die Bildbeschreibung ein 3- Im richtigen Paket im Testverzeichnis müssen Sie eine Java-Klasse erstellen (ich empfehle die Verwendung von Test.java). Geben Sie hier die Bildbeschreibung ein 4- Geben Sie in der erstellten Klasse '@Test' ein. Wählen Sie dann unter den Optionen, die IntelliJ Ihnen bietet, "JUnitx" zum Klassenpfad hinzufügen aus. 5- Schreiben Sie Ihre Testmethode in Ihre Testklasse. Die Methodensignatur lautet wie folgt:Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

@Test
public void test<name of original method>(){
...
}

Sie können Ihre Aussagen wie folgt machen:

Assertions.assertTrue(f.flipEquiv(node1_1, node2_1));

Dies sind die Importe, die ich hinzugefügt habe:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

Geben Sie hier die Bildbeschreibung ein

Dies ist der Test, den ich geschrieben habe: Geben Sie hier die Bildbeschreibung ein

Sie können Ihre Methoden wie folgt überprüfen:

Assertions.assertEquals(<Expected>,<actual>);
Assertions.assertTrue(<actual>);
...

Um Ihre Unit-Tests auszuführen, klicken Sie mit der rechten Maustaste auf den Test und klicken Sie auf Ausführen. Geben Sie hier die Bildbeschreibung ein

Wenn Ihr Test erfolgreich ist, sieht das Ergebnis wie folgt aus: Geben Sie hier die Bildbeschreibung ein

Ich hoffe, es hilft. Sie können die Struktur des Projekts in GitHub https://github.com/m-vahidalizadeh/problem_solving_project sehen .

Mohammad
quelle
12
Liebe deine Antwort, es ist das beste "How-to"!
Alisa
4
Ich bin froh, dass meine Antwort hilfreich war. Danke für deinen Kommentar.
Mohammad
1
So sollten Tutorials aussehen. sauber, prägnant, vollständiges Beispiel. Sehr gut.
Jack Of Blades
1
Vielen Dank Jack. Ich bin froh, dass Sie es hilfreich fanden.
Mohammad
18

Dies ist eine sehr allgemeine Frage, und es gibt viele Möglichkeiten, wie sie beantwortet werden kann.

Wenn Sie JUnit zum Erstellen der Tests verwenden möchten, müssen Sie Ihre Testfallklasse erstellen und dann einzelne Testmethoden erstellen, die die spezifische Funktionalität Ihrer Klasse / des zu testenden Moduls testen (einzelne Testfallklassen sind normalerweise einer einzelnen "Produktions" -Klasse zugeordnet, die wird getestet) und führen innerhalb dieser Methoden verschiedene Operationen aus und vergleichen die Ergebnisse mit den korrekten. Es ist besonders wichtig, möglichst viele Eckfälle abzudecken.

In Ihrem speziellen Beispiel könnten Sie beispielsweise Folgendes testen:

  1. Eine einfache Addition zwischen zwei positiven Zahlen. Fügen Sie sie hinzu und überprüfen Sie, ob das Ergebnis Ihren Erwartungen entspricht.
  2. Eine Addition zwischen einer positiven und einer negativen Zahl (die ein Ergebnis mit dem Vorzeichen des ersten Arguments zurückgibt).
  3. Eine Addition zwischen einer positiven und einer negativen Zahl (die ein Ergebnis mit dem Vorzeichen des zweiten Arguments zurückgibt).
  4. Eine Addition zwischen zwei negativen Zahlen.
  5. Ein Zusatz, der zu einem Überlauf führt.

Um die Ergebnisse zu überprüfen, können Sie verschiedene assertXXX-Methoden aus der org.junit.Assert-Klasse verwenden (der Einfachheit halber können Sie statische org.junit.Assert. * Importieren). Diese Methoden testen eine bestimmte Bedingung und schlagen den Test fehl, wenn er nicht validiert wird (optional mit einer bestimmten Nachricht).

Beispiel einer Testfallklasse in Ihrem Fall (ohne die definierten Methodeninhalte):

import static org.junit.Assert.*;

public class AdditionTests {
    @Test
    public void testSimpleAddition() { ... }


    @Test
    public void testPositiveNegativeAddition() { ... }


    @Test
    public void testNegativePositiveAddition() { ... }


    @Test
    public void testNegativeAddition() { ... }


    @Test
    public void testOverflow() { ... }
}

Wenn Sie nicht daran gewöhnt sind, Komponententests zu schreiben, sondern Ihren Code durch Schreiben von Ad-hoc-Tests testen, die Sie dann "visuell" validieren (z. B. schreiben Sie eine einfache Hauptmethode, die über die Tastatur eingegebene Argumente akzeptiert und dann die Ergebnisse ausdruckt - und dann geben Sie immer wieder Werte ein und überprüfen sich selbst, ob die Ergebnisse korrekt sind. Dann können Sie beginnen, indem Sie solche Tests im obigen Format schreiben und die Ergebnisse mit der richtigen assertXXX-Methode validieren, anstatt sie manuell durchzuführen. Auf diese Weise können Sie den Test viel einfacher erneut ausführen, als wenn Sie manuelle Tests durchführen müssten.

Seramme
quelle
8

Schauen Sie sich, wie bereits bei @CoolBeans erwähnt, jUnit an . Hier ist ein kurzes Tutorial , um Ihnen den Einstieg in jUnit 4.x zu erleichtern

Wenn Sie wirklich mehr über das Testen und die testgetriebene Entwicklung (TDD) erfahren möchten, empfehlen wir Ihnen, das folgende Buch von Kent Beck zu lesen : Testgetriebene Entwicklung anhand eines Beispiels .

vladmore
quelle
6

Andere Antworten haben Ihnen gezeigt, wie Sie mit JUnit Testklassen einrichten. JUnit ist nicht das einzige Java-Testframework. Die Konzentration auf die technischen Details der Verwendung eines Frameworks beeinträchtigt jedoch die wichtigsten Konzepte, die Ihre Handlungen leiten sollten, und ich werde darauf eingehen.

  • Beim Testen (aller Arten aller Arten von Dingen) wird das tatsächliche Verhalten von etwas (The System Under Test, SUT) mit dem erwarteten Verhalten verglichen .

  • Automatisierte Tests können mit einem Computerprogramm durchgeführt werden. Da dieser Vergleich von einem unflexiblen und unintelligenten Computerprogramm durchgeführt wird, muss das erwartete Verhalten genau und eindeutig bekannt sein.

  • Was von einem Programm oder einem Teil eines Programms (einer Klasse oder Methode) erwartet wird, ist seine Spezifikation . Für das Testen von Software ist daher eine Spezifikation für das SUT erforderlich. Dies kann eine explizite Beschreibung oder eine implizite Angabe in Ihrem Kopf dessen sein, was erwartet wird.

  • Das automatisierte Testen von Einheiten erfordert daher eine genaue und eindeutige Angabe der Klasse oder Methode, die Sie testen.

  • Aber Sie brauchten diese Spezifikation, als Sie diesen Code schreiben wollten. Ein Teil dessen, worum es beim Testen geht, beginnt also tatsächlich, bevor Sie auch nur eine Zeile des SUT schreiben. Die Testtechnik von Test Driven Development (TDD) bringt diese Idee auf das Äußerste und lässt Sie den Unit-Test-Code erstellen, bevor Sie den zu testenden Code schreiben.

  • Unit-Test-Frameworks testen Ihr SUT mithilfe von Assertions . Eine Zusicherung ist ein logischer Ausdruck (ein Ausdruck mit einem booleanErgebnistyp; ein Prädikat ), der sein muss, truewenn sich das SUT korrekt verhält. Die Spezifikation muss daher als Behauptung ausgedrückt (oder erneut ausgedrückt) werden.

  • Eine nützliche Technik, um eine Spezifikation als Behauptungen auszudrücken, ist die vertragliche Programmierung . Diese Angaben beziehen sich auf Nachbedingungen . Eine Nachbedingung ist eine Aussage über den öffentlich sichtbaren Zustand des SUT nach Rückkehr von einer Methode oder einem Konstruktor. Einige Methoden haben Nachbedingungen, die Invarianten sind. Dies sind Prädikate, die vor und nach der Ausführung der Methode wahr sind. Man kann auch sagen, dass eine Klasse Invarianten hat, die Nachbedingungen jedes Konstruktors und jeder Methode der Klasse sind und daher immer wahr sein sollten. Nachbedingungen (und Invarianten) werden nur als sichtbarer Publizitätszustand ausgedrückt: publicund protectedFelder, die von zurückgegebenen Werte vonpublicund protectedMethoden (wie Getter) und der öffentlich sichtbare Status von Objekten, die (als Referenz) an Methoden übergeben werden.


Viele Anfänger stellen hier Fragen, wie sie Code testen können, indem sie den Code präsentieren, ohne jedoch die Spezifikation für diesen Code anzugeben. Wie diese Diskussion zeigt, ist es unmöglich für jedermann eine gute Antwort auf eine solche Frage zu geben, denn bestenfalls Potential answereres müssen erraten , die Spezifikation und könnte so falsch tun. Der Fragesteller der Frage offenbar nicht verstehen , die Bedeutung einer Spezifikation, und ist somit ein Anfänger, der die Grundlagen verstehen , muß ich hier beschrieben habe , bevor versuchen , einigen Test - Code zu schreiben.

Raedwald
quelle