Unittests

Tests sind ein exzellenter Weg der Gewährleistung von Stabilität und Fehlerfreiheit in der Anwendungsentwicklung. Sie dienen als interaktive Dokumentation und erlauben Codeveränderungen ohne Angst davor, bereits bestehende Funktionalität zu zerstören. D bietet mit unittest-Blöcken eine bequeme, native Syntax, die überall in einem D-Modul eingesetzt werden kann, um Quellcode-Funktionalität zu prüfen.

// Unittest der Funktion myAbs
unittest
{
    assert(myAbs(-1) == 1);
    assert(myAbs(1)  == 1);
}

Dies erlaubt unkomplizierte testgetriebene Entwicklung auf Abruf.

Ausführung von unittest-Blöcken

unittest-Blöcke können beliebigen Code enthalten, der nur kompiliert und ausgeführt wird, wenn das DMD-Compiler-Flag -unittest gesetzt ist. Auch DUB bietet die Kompilierung und Ausführung von Unittests mit dem Befehl dub test an.

Funktionsnachweis mittels assert

Typischerweise enthalten unittests assert-Ausdrücke, die die Funktionalität einer gegebenen Funktion sicherstellen. unittest-Blöcke befinden sich in der Regel in der Nähe der einer Funktionsdefinition oder sogar in Klassen und Strukturen.

Erhöhung der Code-Abdeckung

Unittests sind eine mächtige Waffe für die Entwickung robuster Anwendungen. Ein Indikator für den Grad der Überprüfung des Codes durch Tests ist die Code-Abdeckung (engl.: code coverage - Verhältnis ausgeführter zu existierender Codezeilen). Der DMD-Compiler erlaubt eine einfache Berichterstellung der Code-Abdeckung durch Hinzufügen von -cov. Damit wird für jedes Modul eine .lst-Datei mit detailierten Statistiken erzeugt.

Da der Compiler Attribute von Template-Quellcode automatisch ableiten kann, ist es ein gängiges Muster, Unittests mit Annotationen zu versehen, um die Verwendung gewünschter Attribute sicherzustellen:

unittest @safe @nogc nothrow pure
{
    assert(myAbs() == 1);
}

Weiterführende Quellen

rdmd playground.d