Inhaltsverzeichnis

  • Testen mit JUnit in Netbeans

    • Vorbereitungen

    • Anpassung der Tests

    • Durchführung der Tests

    • Aufgaben

    • Dateien zu diesem Kapitel


Testen mit JUnit in Netbeans

Bei größeren Programmen ist es sinnvoll, Teile von Programmen automatisch testen zu lassen. Dadurch ist es beispielsweise möglich, zu überprüfen, ob die Änderung an einer Stelle im Programm nicht aus Versehen andere Abschnitte beeinflusst, die sich dadurch anders verhalten als gewünscht.

Im folgenden wird betrachtet, wie solche Tests mit Hilfe von Netbeans und jUnit 4 erstellt werden können.

== Testen mit JUnit in Netbeans Bei größeren Programmen ist es sinnvoll, Teile von Programmen automatisch testen zu lassen. Dadurch ist es beispielsweise möglich, zu überprüfen, ob die Änderung an einer Stelle im Programm nicht aus Versehen andere Abschnitte beeinflusst, die sich dadurch anders verhalten als gewünscht. Im folgenden wird betrachtet, wie solche Tests mit Hilfe von Netbeans und http://junit.org/junit4/[jUnit 4] erstellt werden können.

Vorbereitungen

Nach dem Erstellen eines neuen Projekts erstellen wir eine Klasse namens Vektor, die einige Grundrechenarten von Vektoren definiert, nämlich die Addition, die Subtraktion, das Skalarprodukt und das Kreuzprodukt.

Der Code von Vektor.java könnte beispielsweise so ausssehen:

=== Vorbereitungen Nach dem Erstellen eines neuen Projekts erstellen wir eine Klasse namens `Vektor`, die einige Grundrechenarten von Vektoren definiert, nämlich die Addition, die Subtraktion, das Skalarprodukt und das Kreuzprodukt. Der Code von `Vektor.java` könnte beispielsweise so ausssehen:
public class Vektor {
    private double v1=0,v2=0,v3=0;

    public Vektor(double v1,double v2, double v3){
        this.v1=v1;
        this.v2=v2;
        this.v3=v3;
    }

    public Vektor plus(Vektor that){
        return new Vektor(this.v1+that.v1,this.v2+that.v2,this.v3+that.v3);
    }

    public Vektor minus(Vektor that){
        return new Vektor(this.v1-that.v1,this.v2-that.v2,this.v3-that.v3);
    }

    public double skalar(Vektor that){
        return this.v1*that.v1+this.v2*that.v2+this.v3*that.v3;
    }

    public Vektor kreuz(Vektor that){
        return new Vektor(this.v2*that.v3-this.v3*that.v2,-(this.v1*that.v3-this.v3*that.v1),this.v1*that.v2-this.v2*that.v1);
    }

    @Override
    public String toString(){
        return "("+v1+","+v2+","+v3+")";
    }
}
Java
[source,java] ---- public class Vektor { private double v1=0,v2=0,v3=0; public Vektor(double v1,double v2, double v3){ this.v1=v1; this.v2=v2; this.v3=v3; } public Vektor plus(Vektor that){ return new Vektor(this.v1+that.v1,this.v2+that.v2,this.v3+that.v3); } public Vektor minus(Vektor that){ return new Vektor(this.v1-that.v1,this.v2-that.v2,this.v3-that.v3); } public double skalar(Vektor that){ return this.v1*that.v1+this.v2*that.v2+this.v3*that.v3; } public Vektor kreuz(Vektor that){ return new Vektor(this.v2*that.v3-this.v3*that.v2,-(this.v1*that.v3-this.v3*that.v1),this.v1*that.v2-this.v2*that.v1); } @Override public String toString(){ return "("+v1+","+v2+","+v3+")"; } } ----

Im Folgenden soll überprüft werden, ob diese Rechenoperationen korrekt implementiert wurden.

Dazu erstellen wir zur Klasse Vektor eine Testklasse. In Netbeans funktioniert das folgendermaßen:

  • Klick mit der rechten Maustaste auf die Datei Vektor.java

  • Wähle Tools → Create/Update Tests

Im Folgenden soll überprüft werden, ob diese Rechenoperationen korrekt implementiert wurden. Dazu erstellen wir zur Klasse `Vektor` eine _Testklasse_. In Netbeans funktioniert das folgendermaßen: * Klick mit der rechten Maustaste auf die Datei `Vektor.java` * Wähle *Tools -> Create/Update Tests*
  • Als Klassenname wird VektorTest vorgeschlagen, unter Generated Code die beiden obersten Einträge abwählen.

Nach einem Klick auf OK wird automatisch die Datei VektorTest.java angelegt, die für jede Methode aus Vektor.java einen Test anlegt, der noch angepasst werden muss. Hier findest du eine mögliche, von Netbeans erzeugte Datei VektorTest.java.

* Als Klassenname wird VektorTest vorgeschlagen, unter _Generated Code_ die beiden obersten Einträge abwählen. Nach einem Klick auf OK wird automatisch die Datei `VektorTest.java` angelegt, die für jede Methode aus `Vektor.java` einen Test anlegt, der noch angepasst werden muss. <<tags_b,Hier>> findest du eine mögliche, von Netbeans erzeugte Datei `VektorTest.java`.

Eine mögliche Datei VektorTest.java nach der Generierung durch Netbeans

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package vektorrechnung;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author menze
 */
public class VektorTest {

    public VektorTest() {
    }

    @BeforeClass
    public static void setUpClass() {
    }

    @AfterClass
    public static void tearDownClass() {
    }

    /**
     * Test of plus method, of class Vektor.
     */
    @Test
    public void testPlus() {
        System.out.println("plus");
        Vektor that = null;
        Vektor instance = null;
        Vektor expResult = null;
        Vektor result = instance.plus(that);
        assertEquals(expResult, result);
        // TODO review the generated test code and remove the default call to fail.
        fail("The test case is a prototype.");
    }

    /**
     * Test of minus method, of class Vektor.
     */
    @Test
    public void testMinus() {
        System.out.println("minus");
        Vektor that = null;
        Vektor instance = null;
        Vektor expResult = null;
        Vektor result = instance.minus(that);
        assertEquals(expResult, result);
        // TODO review the generated test code and remove the default call to fail.
        fail("The test case is a prototype.");
    }

    /**
     * Test of skalar method, of class Vektor.
     */
    @Test
    public void testSkalar() {
        System.out.println("skalar");
        Vektor that = null;
        Vektor instance = null;
        double expResult = 0.0;
        double result = instance.skalar(that);
        assertEquals(expResult, result, 0.0);
        // TODO review the generated test code and remove the default call to fail.
        fail("The test case is a prototype.");
    }

    /**
     * Test of kreuz method, of class Vektor.
     */
    @Test
    public void testKreuz() {
        System.out.println("kreuz");
        Vektor that = null;
        Vektor instance = null;
        Vektor expResult = null;
        Vektor result = instance.kreuz(that);
        assertEquals(expResult, result);
        // TODO review the generated test code and remove the default call to fail.
        fail("The test case is a prototype.");
    }


    /**
     * Test of toString method, of class Vektor.
     */
    @Test
    public void testToString() {
        System.out.println("toString");
        Vektor instance = null;
        String expResult = "";
        String result = instance.toString();
        assertEquals(expResult, result);
        // TODO review the generated test code and remove the default call to fail.
        fail("The test case is a prototype.");
    }

}
Java

Zurück zur Hauptseite

== Eine mögliche Datei `VektorTest.java` nach der Generierung durch Netbeans [source,java] ---- /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package vektorrechnung; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author menze */ public class VektorTest { public VektorTest() { } @BeforeClass public static void setUpClass() { } @AfterClass public static void tearDownClass() { } /** * Test of plus method, of class Vektor. */ @Test public void testPlus() { System.out.println("plus"); Vektor that = null; Vektor instance = null; Vektor expResult = null; Vektor result = instance.plus(that); assertEquals(expResult, result); // TODO review the generated test code and remove the default call to fail. fail("The test case is a prototype."); } /** * Test of minus method, of class Vektor. */ @Test public void testMinus() { System.out.println("minus"); Vektor that = null; Vektor instance = null; Vektor expResult = null; Vektor result = instance.minus(that); assertEquals(expResult, result); // TODO review the generated test code and remove the default call to fail. fail("The test case is a prototype."); } /** * Test of skalar method, of class Vektor. */ @Test public void testSkalar() { System.out.println("skalar"); Vektor that = null; Vektor instance = null; double expResult = 0.0; double result = instance.skalar(that); assertEquals(expResult, result, 0.0); // TODO review the generated test code and remove the default call to fail. fail("The test case is a prototype."); } /** * Test of kreuz method, of class Vektor. */ @Test public void testKreuz() { System.out.println("kreuz"); Vektor that = null; Vektor instance = null; Vektor expResult = null; Vektor result = instance.kreuz(that); assertEquals(expResult, result); // TODO review the generated test code and remove the default call to fail. fail("The test case is a prototype."); } /** * Test of toString method, of class Vektor. */ @Test public void testToString() { System.out.println("toString"); Vektor instance = null; String expResult = ""; String result = instance.toString(); assertEquals(expResult, result); // TODO review the generated test code and remove the default call to fail. fail("The test case is a prototype."); } } ---- <<tags_@,Zurück zur Hauptseite>>

Anpassung der Tests

So kann beispielsweise der Test der Addition angepasst werden zu

=== Anpassung der Tests So kann beispielsweise der Test der Addition angepasst werden zu

Zu testende Methode

public Vektor plus(Vektor that){
    return new Vektor(this.v1+that.v1,this.v2+that.v2,this.v3+that.v3);
}
Java
== Zu testende Methode [source,java,indent=0] ---- public Vektor plus(Vektor that){ return new Vektor(this.v1+that.v1,this.v2+that.v2,this.v3+that.v3); } ----

Anwendung

Vektor v1=new Vektor(1,2,3);
Vektor v2=new Vektor(2,3,5);
Vektor ergebnis=v1.plus(v2);
Java
== Anwendung [source,java] ---- Vektor v1=new Vektor(1,2,3); Vektor v2=new Vektor(2,3,5); Vektor ergebnis=v1.plus(v2); ----

Prototyp

@Test
public void testPlus() {
    System.out.println("plus");
    Vektor that = null;
    Vektor instance = null;
    Vektor expResult = null;
    Vektor result = instance.plus(that);
    assertEquals(expResult, result);
    // TODO review the generated test code and remove the default call to fail.
    fail("The test case is a prototype.");
}
Java
== Prototyp [source,java,indent=0] ---- @Test public void testPlus() { System.out.println("plus"); Vektor that = null; Vektor instance = null; Vektor expResult = null; Vektor result = instance.plus(that); assertEquals(expResult, result); // TODO review the generated test code and remove the default call to fail. fail("The test case is a prototype."); } ----

Angepasster Prototyp

@Test
public void testPlus() {
    System.out.println("plus");
    Vektor that = new Vektor(1,2,3); // Vektor für that erzeugen
    Vektor instance = new Vektor(2,3,5); // unser Vektor
    Vektor expResult = new Vektor(3.0,5.0,8.0); // erwartetes Resultat
    Vektor result = instance.plus(that);
    assertEquals(expResult.toString(),result.toString());
}
Java
== Angepasster Prototyp [source,java,indent=0 ] ---- @Test public void testPlus() { System.out.println("plus"); Vektor that = new Vektor(1,2,3); // Vektor für that erzeugen Vektor instance = new Vektor(2,3,5); // unser Vektor Vektor expResult = new Vektor(3.0,5.0,8.0); // erwartetes Resultat Vektor result = instance.plus(that); assertEquals(expResult.toString(),result.toString()); } ----

Kurzschreibweise

@Test
public void testPlus() {
    System.out.println("plus");
    assertEquals(""+new Vektor(1,2,3).plus(new Vektor(2,3,5)), "(3.0,5.0,8.0)");
}
Java
== Kurzschreibweise [source,java,indent=0 ] ---- @Test public void testPlus() { System.out.println("plus"); assertEquals(""+new Vektor(1,2,3).plus(new Vektor(2,3,5)), "(3.0,5.0,8.0)"); } ----

assertEquals vergleicht dabei zwei Objekte auf Gleichheit. Neben dieser Überprüfung auf Gleichheit zweier Objekte gibt es noch viele andere Tests. Eine Übersicht aller Möglichkeiten findet man hier.

Der Versuch, eine Gleichheit der Vektoren result und expResult über

assertEquals(expResult,result);
Java

zu überprüfen, scheitert an der Tatsache, dass diese Instanzen zwar jeweils die gleichen Einträge haben, aber eben unterschiedliche Instanzen des selben Objekts sind.

Deshalb vergleichen wir mit toString() die Repräsentationen der Instanzen als Zeichenketten, um die Gleichheit zu überprüfen. Bei einfachen Objekten wie Strings funktioniert dieser Vergleich.

`assertEquals` vergleicht dabei zwei Objekte auf Gleichheit. Neben dieser Überprüfung auf Gleichheit zweier Objekte gibt es noch viele andere Tests. Eine Übersicht aller Möglichkeiten findet man https://github.com/junit-team/junit4/wiki/Assertions[hier]. [WARNING] ==== Der Versuch, eine Gleichheit der Vektoren `result` und `expResult` über [source, Java] ---- assertEquals(expResult,result); ---- zu überprüfen, scheitert an der Tatsache, dass diese Instanzen zwar jeweils die gleichen Einträge haben, aber eben unterschiedliche Instanzen des selben Objekts sind. Deshalb vergleichen wir mit `toString()` die Repräsentationen der Instanzen als Zeichenketten, um die Gleichheit zu überprüfen. Bei einfachen Objekten wie Strings funktioniert dieser Vergleich. ====

Man kann den Code des Beispiels auch deutlich knapper schreiben, wie z. B.

    @Test
    public void testPlus() {
        System.out.println("plus");
        assertEquals(""+new Vektor(1,2,3).plus(new Vektor(2,3,5)), "(3.0,5.0,8.0)");
    }
Java

Im linken Teil von assertEquals werden die beiden Vektoren addiert und das Ergebnis durch die doppelten Anführungszeichen und dem Pluszeichen in einen String umgewandelt. Dieses wird mit dem erwarteten String verglichen.

[NOTE] ==== Man kann den Code des Beispiels auch deutlich knapper schreiben, wie z. B. [source,java] ---- @Test public void testPlus() { System.out.println("plus"); assertEquals(""+new Vektor(1,2,3).plus(new Vektor(2,3,5)), "(3.0,5.0,8.0)"); } ---- Im linken Teil von `assertEquals` werden die beiden Vektoren addiert und das Ergebnis durch die doppelten Anführungszeichen und dem Pluszeichen in einen String umgewandelt. Dieses wird mit dem erwarteten String verglichen. ====

Durchführung der Tests

Um die Tests durchführen zu lassen, kann man über Run → Test File den Test durchführen lassen.

Je nach Erfolg oder Misserfolg erscheint eine entsprechende Ausgabe in Netbeans.

=== Durchführung der Tests Um die Tests durchführen zu lassen, kann man über *Run -> Test File* den Test durchführen lassen. Je nach Erfolg oder Misserfolg erscheint eine entsprechende Ausgabe in Netbeans.

Aufgaben

  1. Passe alle Tests der generierten Datei so an, dass die Tests korrekt durchlaufen.

    Eine mögliche Lösung findest du hier.

  2. Baue absichtliche Fehler in die Berechnung des Kreuz- und Skalarprodukts ein und verifiziere, dass der Test danach nicht mehr durchläuft.

  3. Probiere einige andere der Testarten aus, die hier zu finden sind.

=== Aufgaben . Passe alle Tests der generierten Datei so an, dass die Tests korrekt durchlaufen. + Eine mögliche Lösung findest du <<tags_A,hier>>. . Baue absichtliche Fehler in die Berechnung des Kreuz- und Skalarprodukts ein und verifiziere, dass der Test danach nicht mehr durchläuft. . Probiere einige andere der Testarten aus, die https://github.com/junit-team/junit4/wiki/Assertions[hier] zu finden sind.

Mögliche Lösung für die Datei VektorTest

package vektorrechnung;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

public class VektorTest {

    public VektorTest() {
    }

    @BeforeClass
    public static void setUpClass() {
        System.out.println("Test aller Methoden von Vektor");
    }

    @AfterClass
    public static void tearDownClass() {
    }

    /**
     * Test of plus method, of class Vektor.
     */
    @Test
    public void testPlus() {
        System.out.println("plus");
        Vektor that = new Vektor(1,2,3);
        Vektor instance = new Vektor(2,3,5);
        Vektor expResult = new Vektor(3.0,5.0,8.0);
        Vektor result = instance.plus(that);
        assertEquals(expResult.toString(),result.toString());
    }

    /**
     * Test of minus method, of class Vektor.
     */
    @Test
    public void testMinus() {
        System.out.println("minus");
        Vektor that = new Vektor(1,2,3);
        Vektor instance = new Vektor(2,3,5);
        Vektor expResult = new Vektor(1,1,2);
        Vektor result = instance.minus(that);
        assertEquals(expResult.toString(), result.toString());
    }

    /**
     * Test of skalar method, of class Vektor.
     */
    @Test
    public void testSkalar() {
        System.out.println("skalar");
        Vektor that = new Vektor(1,2,3);
        Vektor instance = new Vektor(2,4,3);
        double expResult = 19.0;
        double result = instance.skalar(that);
        assertEquals(expResult, result, 0.1);
    }

    /**
     * Test of kreuz method, of class Vektor.
     */
    @Test
    public void testKreuz() {
        System.out.println("kreuz");
        Vektor that = new Vektor(2,4,5);
        Vektor instance = new Vektor(1,2,3);
        Vektor expResult = new Vektor(-2,1,0);
        Vektor result = instance.kreuz(that);
        assertEquals(expResult.toString(), result.toString());
    }

    /**
     * Test of toString method, of class Vektor.
     */
    @Test
    public void testToString() {
        System.out.println("toString");
        Vektor instance = new Vektor(1,2,3);
        String expResult = "(1.0,2.0,3.0)";
        String result = instance.toString();
        assertEquals(expResult, result);
    }
}
Java

Zurück zur Hauptseite dieses Artikels

=== Mögliche Lösung für die Datei `VektorTest` [source,java] ---- package vektorrechnung; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; public class VektorTest { public VektorTest() { } @BeforeClass public static void setUpClass() { System.out.println("Test aller Methoden von Vektor"); } @AfterClass public static void tearDownClass() { } /** * Test of plus method, of class Vektor. */ @Test public void testPlus() { System.out.println("plus"); Vektor that = new Vektor(1,2,3); Vektor instance = new Vektor(2,3,5); Vektor expResult = new Vektor(3.0,5.0,8.0); Vektor result = instance.plus(that); assertEquals(expResult.toString(),result.toString()); } /** * Test of minus method, of class Vektor. */ @Test public void testMinus() { System.out.println("minus"); Vektor that = new Vektor(1,2,3); Vektor instance = new Vektor(2,3,5); Vektor expResult = new Vektor(1,1,2); Vektor result = instance.minus(that); assertEquals(expResult.toString(), result.toString()); } /** * Test of skalar method, of class Vektor. */ @Test public void testSkalar() { System.out.println("skalar"); Vektor that = new Vektor(1,2,3); Vektor instance = new Vektor(2,4,3); double expResult = 19.0; double result = instance.skalar(that); assertEquals(expResult, result, 0.1); } /** * Test of kreuz method, of class Vektor. */ @Test public void testKreuz() { System.out.println("kreuz"); Vektor that = new Vektor(2,4,5); Vektor instance = new Vektor(1,2,3); Vektor expResult = new Vektor(-2,1,0); Vektor result = instance.kreuz(that); assertEquals(expResult.toString(), result.toString()); } /** * Test of toString method, of class Vektor. */ @Test public void testToString() { System.out.println("toString"); Vektor instance = new Vektor(1,2,3); String expResult = "(1.0,2.0,3.0)"; String result = instance.toString(); assertEquals(expResult, result); } } ---- <<tags_@,Zurück zur Hauptseite dieses Artikels>>

Dateien zu diesem Kapitel

Das Grundprogramm ohne Lösungen kannst du hier als gezipptes Netbeans-Projekt herunterladen:

=== Dateien zu diesem Kapitel Das Grundprogramm ohne Lösungen kannst du hier als gezipptes Netbeans-Projekt herunterladen:

Dateiname

Vektorrechnung.zip

Größe in Bytes

19736

Einfügezeitpunkt

18.9.2017, 15:20:27