Unit-Tests

Einführung in Unit-Tests

Unit-Tests sind eine Softwaretestmethode zur Überprüfung der Funktionalität einzelner Komponenten oder Einheiten eines Programms, die vom Rest der Anwendung isoliert sind.

Eine Unit ist in der Regel der kleinste testbare Teil eines Programms, z. B. eine Funktion, eine Methode, eine Klasse oder ein Skript. Durch die Aufteilung komplexer Skripte oder Algorithmen in diese kleineren Einheiten können präzise und zielgerichtete Tests entwickelt werden, um die Funktionalität jeder Komponente zu validieren.

Darstellung von Puzzleteilen als Analogie für Komponenten in einem System. Beim Unit-Test wird der Fokus auf ein einzelnes Teil (oder eine Komponente) und die angrenzenden Teile gelegt, nicht auf das gesamte System.

Puzzleteile, die einzelne Komponenten einer Anwendung darstellen. Durch Unit-Tests wird bestätigt, dass jede Komponente für sich genommen ordnungsgemäß funktioniert.

Die Bedeutung von Unit-Tests

Wenn man frühzeitig Unit-Tests an den einzelnen Units durchführt, können mögliche Fehler erkannt und behoben werden, was zu zuverlässigerem Code und weniger komplizierten und zeitaufwendigen Debugging-Projekten führt. Zudem wird die Entwicklung modularer und wartungsfreundlicher Software unterstützt, was wiederum die Codequalität verbessert.

Chancen und Herausforderungen von Unit-Tests

Unit-Tests bieten zahlreiche Vorteile:

  • Unit-Tests sind oft einfacher zu schreiben und schneller durchzuführen als Tests des gesamten Systems oder noch umfassendere Tests.
  • Es ist wahrscheinlich am einfachsten, Fehler zu einem frühen Zeitpunkt zu erkennen und zu isolieren.
  • So können Sie mögliche Probleme mit anderen Teilen der Software leichter identifizieren und die Anzahl der Interaktionen mit Subsystemen auf ein Minimum beschränken.
  • Sie können bereits in frühen Entwicklungsstadien mit dem Testen beginnen, ohne auf die Fertigstellung der gesamten Anwendung warten zu müssen. 

Eine Herausforderung besteht jedoch darin, dass durch das isolierte Testen einzelner Units möglicherweise nicht alle Probleme erkannt werden.

Der richtige Zeitpunkt für Unit-Tests

Um die hohe Qualität des Codes zu gewährleisten und die Auswirkungen von Änderungen am Code zu erfassen, sollten während des gesamten Entwicklungsprozesses Unit-Tests durchgeführt werden:

  • In der Entwicklungsphase: Schreiben Sie gleichzeitig mit der Entwicklung neuer Funktionen auch Unit-Tests. Dieser Ansatz stellt sicher, dass jede Komponente von Anfang an wie vorgesehen funktioniert.
  • Beim Refactoring: Verwenden Sie Unit-Tests, um sicherzustellen, dass das Refactoring das erwartete Verhalten des Codes nicht verändert.
  • Nach Fehlerbehebungen: Implementieren Sie Unit-Tests für behobene Fehler, um zu verhindern, dass sie in Zukunft erneut auftreten, und um sicherzustellen, dass die Fehlerbehebungen keine negativen Auswirkungen auf andere Softwarefunktionen haben.
  • Vor und während der Integration: Führen Sie Unit-Tests durch, bevor Sie Änderungen in den Hauptcode einbinden und in Ihre Pipeline für die kontinuierliche Integration (CI) einfügen. Dadurch wird verhindert, dass durch neuen Code zusätzliche Fehler entstehen, während gleichzeitig eine stabile Codebasis aufrechterhalten wird.

Die Softwaretest-Pyramide

Die Durchführung von Unit-Tests zu Beginn und während des gesamten Softwareentwicklungsprozesses trägt zu einer besseren Codequalität bei. Unit-Tests sind jedoch nur ein Teil einer umfassenden Strategie. Die Softwaretest-Pyramide veranschaulicht die verschiedenen Testebenen – Unit-Test, Integrationstest und Systemtest – und hebt deren Granularität und Häufigkeit hervor. Diese Pyramide bietet einen strukturierten Ansatz für die Koordination und Priorisierung von Testverfahren und hebt die Bedeutung eines ausgewogenen Verhältnisses für eine optimale Softwarequalität hervor.

Diese Testarten weisen folgende Merkmale auf:

  • Unit-Tests, die an der Basis der Pyramide stehen, sind am detailliertesten und werden häufig durchgeführt. Unit-Tests sind in der Regel von geringem Umfang und daher schneller und kostengünstiger zu schreiben und auszuführen. Sie können bereits früh im Entwicklungsprozess implementiert werden und liefern unmittelbares Feedback zur Funktionalität einzelner Komponenten.
  • Integrationstests, die sich in der Mitte der Pyramide befinden, konzentrieren sich auf die Überprüfung der Interaktionen zwischen verschiedenen Komponenten oder Systemen. Diese Integrationstests sind etwas komplexer und zeitaufwendiger als Unit-Tests, aber sie sind unerlässlich, um sicherzustellen, dass die integrierten Komponenten erwartungsgemäß zusammenarbeiten.
  • Systemtests, die an der Spitze der Pyramide stehen, evaluieren die gesamte Anwendung. Systemtests sind umfassender und ressourcenintensiver. Sie werden in der Regel zu einem späteren Zeitpunkt im Entwicklungszyklus durchgeführt, um zu bestätigen, dass das gesamte System die festgelegten Anforderungen erfüllt.

Die Pyramide unterstreicht die Wichtigkeit, eher niedrigschwellige Tests wie Unit-Tests durchzuführen und dafür weniger High-Level-Tests. Ein ausgewogener Ansatz sieht vor, dass bis zum Abschluss des Projekts etwa 70% auf Unit-Tests, 20% auf Integrationstests und 10% auf Systemtests entfallen. Diese Strategie gewährleistet eine solide Grundlage für zuverlässigen Code und reduziert die Wahrscheinlichkeit von Problemen in höheren Testphasen.

Die Unit-Tests bilden die Basis der Pyramide, die Integrationstests liegen in der Mitte und die Systemtests bilden die Spitze. Wenn man sich von unten nach oben bewegt, werden die Tests langsamer und gehen von eher isolierten zu mehr integrierten Tests.

Die Pyramide der Softwaretests, die aus drei Testarten besteht, die einen strukturierten Ansatz für die Verwaltung und Priorisierung von Testbemühungen bieten.

Weitere Varianten von Softwaretests

Zusätzlich zur Granularität und Häufigkeit der Tests, die durch die Pyramide der Softwaretests dargestellt werden, gibt es verschiedene Arten von Testmethoden, die jeweils spezifische Ziele haben, die auf den beabsichtigten Ergebnissen basieren. Ein wichtiger Unterschied besteht zwischen funktionalen und nichtfunktionalen Tests:

  • Bei Funktionstests liegt der Schwerpunkt auf der Überprüfung der korrekten Funktionalität und des korrekten Verhaltens der Software. Beispiele hierfür sind Smoke-Tests, bei denen die grundlegende Funktionalität überprüft wird, und Regressionstests, die sicherstellen, dass neue Code-Änderungen keine negativen Auswirkungen auf bestehende Funktionen haben.
  • Nichtfunktionale Tests bewerten andere kritische Aspekte der Software, wie Benutzerfreundlichkeit, Sicherheit und Stabilität. Dahingegen bewerten Performance-Tests, die häufigste Art von nicht funktionalen Tests, wie effizient eine Software unter bestimmten Bedingungen, wie z. B. Last und Stress, arbeitet.

Durch die Nutzung sowohl funktionaler als auch nicht funktionaler Tests wird sichergestellt, dass die Software ordnungsgemäß funktioniert und Qualitätsstandards erfüllt.

Unit-Tests mit MATLAB

Das Testen von Code ist ein wesentlicher Bestandteil bei der Entwicklung hochwertiger Software. MATLAB® bietet ein fehlerresistentes, integriertes Framework für Unit-Tests, mit dem Sie Unit-Tests schreiben und die Codefunktionalität auf Regressionen überwachen können. Das Framework unterstützt das Schreiben von Tests mithilfe von Klassen und ermöglicht Ihnen so, Ihre Tests logisch zu strukturieren. Zudem können Sie Tests ausführen und Testergebnisse analysieren.

Klassenbasierte Unit-Tests

Bei diesem Ansatz definieren Sie Tests als Methoden innerhalb einer Klasse. MATLAB kann eine generische Vorlage für Sie erstellen und mithilfe von MATLAB Test™ kann ein spezifischer Test für Ihren Code generiert werden. Dieser Ansatz ermöglicht es Ihnen, Skripte und Funktionen innerhalb Ihrer Testmethoden zu testen und dabei die Vorteile der objektorientierten Programmierung mit der Flexibilität zu kombinieren, verschiedene Code-Typen zu testen. Dieses Beispiel veranschaulicht das Schreiben von klassenbasierten Unit-Tests.

Ausführung von Tests

Nachdem Sie die Testdatei gespeichert haben, können Sie den Test über die MATLAB-Symbolleiste ausführen. Sie können aber auch die runtests-Funktion oder die Test Browser-App von MATLAB verwenden, um Tests auszuführen, Ergebnisse anzuzeigen und Fehler interaktiv zu beheben.

Screenshot des „Ausführen“-Abschnitts der Toolbar des MATLAB Editor mit Symbolen für „Tests ausführen“, „Aktuellen Test ausführen“, „Schritt“ und „Stopp“.

Die Option „Run Tests“ in der Symbolleiste des MATLAB Editor. (Siehe Dokumentation.)

Analyse der Testergebnisse

MATLAB bietet Zusammenfassungen, detaillierte Berichte und Code-Abdeckung zur Analyse Ihres Quellcodes.

Für komplexere Anwendungsfälle bietet MATLAB Test zusätzliche Funktionen zur Verbesserung des Testprozesses, wie z. B. die automatische Testgenerierung, ein erweitertes Testmanagement, die Integration in CI/CD-Systeme, eine erweiterte Codeabdeckung und ein Qualitäts-Dashboard. Weitere Informationen über die Analyse von Testergebnissen.

Beispiel für Unit-Tests in MATLAB

Dieses Beispiel zeigt, wie man Unit-Tests an einer einfachen fibonacci-Funktion durchführt. Diese Funktion berechnet die Fibonacci-Folge bis zu einer bestimmten Zahl (n). Damit die Richtigkeit validiert werden kann, stellen wir Beispiel-Eingaben bereit und der Unit-Test überprüft, ob die berechnete Ausgabe mit der erwarteten Ausgabe für die jeweilige Eingabe übereinstimmt. Stimmen die Ergebnisse überein, ist der Test bestanden, andernfalls nicht.

function x = fibonacci (n) 
% Generiert die ersten n Fibonacci-Zahlen
n=6;
x = ones (1,n);
for ii = 3:n;
      x(ii) = x(ii - 1) + x(ii - 2);
end

end
% Dies ist ein automatisch generierter Beispieltest für die Datei fibonacci.m
classdef test fibonacci < matlab.unittest.TestCase

    methods (Test)

        function test_fibonacci (testCase)
            % Spezifizieren Sie die Eingabe(n) von
            % fibonacci
            n = 6;

            % Spezifizieren Sie die erwartete(n) Ausgabe von
            % fibonacci
            expected_x = [1, 1, 2, 3, 5, 8];

            % Führen Sie die Fibonacci-Funktion aus
            actual_x = fibonacci(n);

            testCase.verifyEqual(actual_x,expected_x);

        end
    end
end
Screenshot des MATLAB Test Browser, der den erfolgreichen Unit-Test der Fibonacci-Funktion anzeigt, wobei das grüne Häkchen angibt, dass der Test bestanden wurde.

Durchführung von Unit-Tests in MATLAB. Der MATLAB Test Browser führt einen Unit-Test der fibonacci-Funktion durch, indem er die berechnete Ausgabe mit der erwarteten Ausgabe für die ausgewählten Eingaben vergleicht. Die rechts angezeigte App des MATLAB Test Browser zeigt an, dass der Unit-Test erfolgreich bestanden wurde.


Beispiele und Erläuterungen


Siehe auch: MATLAB Test, softwaretests