Alles grün - alles gut. :)

Unit-Tests – mal eben erklärt…

“Unit Tests? Pff, brauch’ ich nicht.” – “Was ist das?” – “Viiiiel zu aufwändig.”

So oder so ähnlich sind die Reaktionen auf die beiden kleinen, unscheinbaren Wörter, die vor allem nach einem klingen: Eine Menge Arbeit.

Dabei sind Unit-Tests eigentlich gar nicht so kompliziert und definitiv nützlich. Ich möchte euch eine kleine Einführung ins Thema geben, und euch ermutigen, ihnen zumindest eine Chance zu geben.

Am Anfang war die Klasse… oder?

Unit Tests (Modultests im Deutschen) sind schon länger ein Begriff, werden aber dennoch immer noch zu selten eingesetzt, auch wenn hier einige Open Source – Projekte eine Vorreiterrolle einnehmen. Grundsätzlich geht es bei Unit Tests darum, die Funktionen einer Klasse zu testen, und zu prüfen, ob die Ausgabe mit den erwarteten Ergebnissen übereinstimmt.

Ein kleines Beispiel:

using System;

public class TestKlasse
{
    public int Multipliziere(int a, int b)
    {
        return a * b;
    }
}

Zugegeben, das Beispiel ist trivial. Aber zur Demonstration soll es erstmal genügen. Diese Klasse stellt eine Methode zur Verfügung, mit der ich zwei Werte multiplizieren kann.

Um nun die Ausgaben zu testen, erstelle ich einen Black-Box-Test, d.h., ich vergleiche die Ausgabe der Funktion mit meinen erwarteten Werten. Hierbei hilft mir eine Modultest-Software. Ich habe zwei Möglichkeiten:

  • Ich nutze entweder den internen Unit test des Visual Studios, oder…
  • …ich verwende NUnit.

Für dieses Beispiel entscheide ich mich für NUnit. Die Verwendung ist eigentlich recht simpel: Zuerst lädt man sich die NUnit-Installationsdatei herunter und installiert NUnit. Anschließend fügt man dem Projekt eine Klassenbibliothek hinzu. Am Besten erstellt man pro Klasse im Programm eine Klasse zum Testen. Hier in diesem Falle also eine Testklasse für unsere – äh – TestKlasse

using System;
using NUnit.Framework;

[TestFixture]
public class TestKlasseTest
{
    [Test]
    public void MultipliziereTest()
    {
        int a = 5;
        int b = 6;

        TestKlasse TK = new TestKlasse();

        //Grob überschlagen: 5 * 6 = 30
        Assert.AreEqual(30, TK.Multipliziere(a, b));
    }
}

Ok, was ist hier passiert? Nun, zuerst wird dem neuen Projekt die Assembly NUnit.Framework hinzugefügt. Anschließend bekommt die Klasse das Attribut TestFixture, und jede einzelne Testmethode das Attribut Test. Eine Methode im Unit Test hat grundsätzlich den Rückgabewert void und keinen Parameter.

Anschließend wird die Assembly kompilliert. Jetzt kommt wieder NUnit ins Spiel. Bei der Installation wurde eine GUI installiert, über die ihr die Assembly laden könnt. Über “Run” könnt ihr nun den Test ausführen. Ist der Test erfolgreich, solltet ihr nur noch grün sehen…

Alles grün - alles gut. :)

Alles grün - alles gut. :)

Sollte doch noch ein Fehler auftreten, so könnt ihr den Fehler im Quellcode korrigieren und anschließend neu kompillieren. Anschließend könnt ihr einfach erneut auf Run klicken.

Warum Unit tests?

“Ok”, mögt ihr jetzt sagen, “ich soll also extra Arbeit investieren, um ein paar Funktionen zu testen. Und wer zahlt mir das?” Berechtigte Frage. Direkt natürlich keiner, indirekt der Kunde. Folgende Überlegung:

Ich schreibe für den Kunden ein Modul, und benutze keine Unit tests. Das Modul weist Fehler auf, ich muss nachbessern. Der Kunde wünscht nach einiger Zeit eine Erweiterung, ich setzte sie um, und es schleicht sich wieder ein Fehler ein. Ich muss wieder nachbessern. Mein Problem: In der Zeit, wo ich Nachbesserungen vornehmen muss, kann ich keine anderen Aufträge bearbeiten. Schlimmer noch: Eventuell handelt es sich um aufwändigere Nachbesserungen und der Kunde erleidet Verdienstausfälle, die er mir womöglich noch in Rechnung stellen kann.

Habe ich stattdessen Unit tests benutzt, kann ich nach dem Ändern (und ggf. Anpassen des Tests) den Test laufen lassen und sehe sofort, wenn sich etwas nicht wie geplant verhält. Ich habe weniger Verdienstausfälle und der Kunde ist glücklich. So amortisiert sich die zusätzliche Zeit, die man für die Tests investieren muss, recht bald.

Weitere Hinweise…

An dieser Stelle sei auf die offizielle NUnit – Dokumentation verwiesen. Natürlich gibt es an dieser Stelle noch mehr Möglichkeiten: Exceptions, komplexere Klassen, Test-Suiten etc…

Auch sollte man sich einmal mit Testgetriebener Entwicklung beschäftigen, ein sehr interessantes Thema.

2 Gedanken zu „Unit-Tests – mal eben erklärt…

  1. OK, das ist jetzt zum Einstieg ein trivial Beispiel. Aber man sollte natürlich auch oder gerade die Grenzfälle testen: Multiplikation mit 0, Intergerüberlauf beim Ergebnis (wird da auch richtig eine Exception geworfen und abgefangen).

    Und je komplexer der Code ist, desto schwieriger wird es abzuschätzen, ob eine Änderung an einer Stelle Auswirkungen auf Code an anderer Stelle hat. Mit Unit Test lässt sich das schnell überprüfen, ob der komplette Code noch das tut, was er soll.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>