Teil 3: Testen mit Faktor-IPS

Testfall anlegen

Im Projekt faktorips-tutorial-hausratprodukte legen wir unterhalb von produktdaten ein neues IPS Package test an, in dem wir unsere Testfälle ablegen. Dazu wechseln wir wieder in den Model Explorer, markieren das Verzeichnis produktdaten und wählen über das Kontextmenü NeuIPS Package an. Wir legen mit NeuTestfall im Kontextmenü einen neuen Testfall an. Nun wählen wir im Wizard zur Testfallanlage den zuvor angelegten Testfalltyp test.BeitragsberechnungHausratTest aus und geben dem Testfall einen Namen.

testfall anlegen
Figure 1. Neuen Testfall anlegen

Nun öffnet sich der Testfalleditor: Auf der linken Seite befindet sich die Struktur des Testfalls. Sie entspricht der Struktur, die wir im Testfalltypen definiert haben. Auf der rechten Seite sind die Testdaten. Für jedes, im Testfalltypen definierte Attribut, ist hier ein Eingabefeld zu sehen, wobei Eingabewerte weiß und erwartete Werte gelb hinterlegt sind.

testfalleditor fehler
Figure 2. Testfalleditor mit Hinweis auf fehlenden Produktbaustein

Auf der linken Seite müssen wir die Vertragsteile jetzt noch durch Zuordnung von Produktbausteinen ausprägen. Mit dem Button Produktbaustein zuordnen wird der Produktbaustein der aktuellen Vertragsteilklasse ausgewählt.

auswahl produktbaustein
Figure 3. Auswahl eines Produktbausteins mit "Produktbaustein zuordnen"

Wir wählen für unser Beispiel den Produktbaustein HR-Kompakt 2019-07 für HausratVertrag.
Danach fügen wir mit Hinzufügen und anschließend Produktbaustein zuordnen weitere Objekte hinzu: HRD-Grunddeckung-Kompakt 2019-07 für HausratGrunddeckung, und prägen zwei mal HausratZusatzdeckung, jeweils mit HRD-Fahrraddiebstahl 2019-07 und HRD-Überspannung 2019-07 aus. Danach vervollständigen wir den Testfall gemäß folgender Tabelle:

Table 1. Testfall Beitragsberechnung Hausrat
Parameter Wert

Produkt

_HR-Kompakt 2019-07

Grunddeckungstyp

HRD-Grunddeckung-Kompakt 2019-07

Zusatzdeckungstypen

HRD-Fahrraddiebstahl 2019-07
HRD-Überspannung 2019-07

Zahlweise

1 (jährlich)

Postleitzahl

81673 (Tarifzone I)

Versicherungssumme

60.000 EUR

Nettobeitrag gemäß Zahlweise

196,00 EUR

testfall erfasst
Figure 4. Erfasster Testfall

Nun starten wir die Ausführung des Testfalls mit dem Icon Test ausführen(TestCaseRun)in der oberen rechten Ecke des Testfall-Editors. (Der Testfall kann auf zwei Arten gestartet werden. Wir starten mit Test ausführen. Die Variante Ermitteln der erwarteten Werte sehen wir später im Kapitel "Testfälle durch Kopieren erzeugen").

test fehlgeschlagen
Figure 5. Testfallausführung im Testrunner schlägt fehl

Der Editor verrät uns durch einen roten Balken im Titel und durch einen roten Balken im Faktor-IPS Testrunner, dass der Test fehlgeschlagen ist. In den Fehler Details sehen wir, warum. Wir werden daran erinnert, dass wir im Testfalltypen die Prüfungen noch nicht implementiert haben (an der Stelle ist eine Runtime-Exception generiert, deren Nachricht hier angezeigt wird). Holen wir dies also nach:

public class BeitragsberechnungHausratTest extends IpsTestCase2 {
    //...

    /**
     * Fuehrt die zu testende Geschaeftslogik aus.
     *
     * @restrainedmodifiable
     */
    @Override
    public void executeBusinessLogic() {
        // begin-user-code
        inputHausratVertrag.berechneBeitrag();
        // end-user-code
    }

    /**
     * Fuehrt die Pruefungen (Asserts) aus, d.h. vergleicht die erwarteten Werte mit den
     * tatsaechlichen Ergebnissen.
     *
     * @restrainedmodifiable
     */
    @Override
    public void executeAsserts(IpsTestResult result) {
        // begin-user-code
        assertEquals(erwartetHausratVertrag.getNettobeitragZw(),
                inputHausratVertrag.getNettobeitragZw(),
                result);
        // end-user-code
    }

    //...
}

In der Methode executeBusinessLogic() rufen wir die zu testende Geschäftslogik auf: Auf der input-Instanz rufen wir die Methode berechneBeitrag() auf. Faktor-IPS sorgt dafür, dass die Instanz zur Laufzeit die Eingabewerte aus dem jeweiligen Testfall enthält. In der Methode executeAsserts(…​) implementieren wir die Prüfungen. In unserem Fall wollen wir überprüfen, ob der erwartete Nettobeitrag mit dem berechneten Beitrag übereinstimmt. Dazu benutzen wir die assert*-Methoden der Klasse IpsTestCaseBase.

Nun führen wir unseren Testfall erneut aus. Der grüne Balken im Testfalleditor und im Testfallrunner zeigt uns, dass das erwartete Ergebnis und das berechnete Ergebnis überein stimmen.

Machen wir die Gegenprobe und ändern das erwartete Ergebnis:

test fehlgeschlagen 2
Figure 6. Testfall schlägt fehl

Der Testfall schlägt fehl. In den Fehler Details sehen wir, dass der berechnete Wert 196 EUR nicht dem erwarteten Wert entspricht. Wir sehen der Fehlermeldung aber noch nicht an, auf welches Testattribut sie sich bezieht. In unserem Fall ist dies zwar einfach, da wir nur ein erwartetes Attribut vergleichen, aber es können ja durchaus mehrere Attribute in einem Testfall verglichen werden (z.B. die einzelnen Beiträge je Deckung und der Gesamtbeitrag). Hierzu können wir den assert*-Statements eine Referenz auf das Attribut aus der Definition des Testfalltyps mitgeben. Als ersten weiteren Parameter übergeben wir einen String, der das Testobjekt identifiziert, als weiteren Parameter den Namen des fehlerhaften Attributes. Wenn es mehrere Instanzen eines Objekts im Test gibt, muss der Index der Instanz, beginnend bei 0, getrennt von einer Raute angefügt werden, z.B. Zusatzdeckung#0 für die erste Instanz des Objekts Zusatzdeckung. Für das Attribut nettobeitragZw in unserem Beispiel sieht die Implementierung dann wie folgt aus:

/**
 * Fuehrt die Pruefungen (Asserts) aus, d.h. vergleicht die erwarteten Werte mit den
 * tatsaechlichen Ergebnissen.
 *
 * @restrainedmodifiable
 */
@Override
public void executeAsserts(IpsTestResult result) {
    // begin-user-code
    assertEquals(erwartetHausratVertrag.getNettobeitragZw(),
            inputHausratVertrag.getNettobeitragZw(),
            result,
            "HausratVertrag",
            "nettobeitragZw");
    // end-user-code
}

Führen wir nun den Testfall erneut aus (weiterhin mit "falschem" erwartetem Ergebnis), wird auch das entsprechende Attribut auf der Oberfläche rot hinterlegt und die Meldung in den Fehler Details sagt uns nun auch, auf welches Attribut sie sich bezieht:

markierung fehler
Figure 7. Markierung des fehlerhaften Attributs im Testeditor

Damit haben wir einen Testfalltypen komplett implementiert, einen Testfall angelegt und ausgeführt.