Modellierung und Simulation - Modultest: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
Zeile 346: Zeile 346:
  suite = testsuite('TestAddiere');
  suite = testsuite('TestAddiere');
  results = run(suite);
  results = run(suite);
=== TestRunner mit Textausgabe ===
Das ist ein „professioneller Runner“, der einen strukturierten Bericht erzeugt.
import matlab.unittest.TestRunner
runner = TestRunner.withTextOutput;
'''Test ausführen'''
results = runner.run(suite);
'''Beispielausgabe (detaillierter Bericht)'''
Running TestAddiere
TestAddiere/testPositive .... PASSED
TestAddiere/testNegative .... PASSED
TestAddiere/testMixed .... PASSED
Done TestAddiere


= Praktische Übung =
= Praktische Übung =

Version vom 25. Juni 2026, 14:05 Uhr

Autor: Prof. Dr.-Ing. Schneider
Lektion: 11
Termin: 26.06.2026

Einleitung

Modultests bilden die unterste Ebene des Testprozesses und dienen dazu, einzelne Softwareeinheiten frühzeitig und isoliert auf ihre korrekte Funktion zu überprüfen. Ziel ist es, Fehler bereits in einem sehr frühen Entwicklungsstadium zu erkennen, um spätere Integrationsprobleme zu vermeiden und die Gesamtqualität des Systems nachhaltig zu erhöhen. Dabei wird jedes Modul unabhängig von anderen Komponenten getestet, wobei sowohl funktionale Anforderungen als auch typische Fehlerszenarien betrachtet werden. Durch klar definierte Testfälle, reproduzierbare Testumgebungen und objektive Bewertungskriterien stellen Modultests sicher, dass die implementierten Funktionen robust, zuverlässig und spezifikationskonform sind.

Lernziele

Nach dieser Lektion können Sie

  • die Bedeutung von Unit-Tests erklären,
  • MATLAB-Testklassen erstellen,
  • Tests mit dem matlab.unittest Framework durchführen,
  • Test Fixtures verwenden,
  • Fehlerfälle gezielt prüfen,
  • Testberichte interpretieren,
  • Unit-Tests in Entwicklungsprozesse integrieren.

Vorbereitung

  1. Studieren Sie das Video Erste Schritte mit dem MATLAB Unit Test Framework.
  2. Weitere Informationen finden Sie im Artikel Ways to Write Unit Tests.
  3. Besuchen Sie den Online-Kurs Unit Testing
  4. Lassen Sie sich vom Copilot helfen einen Test zu generieren.

1. Motivation

Bei wissenschaftlicher Software entstehen häufig Fehler durch:

  • Änderungen am Algorithmus
  • Erweiterungen bestehender Funktionen
  • Refactoring
  • Teamarbeit

Unit-Tests stellen sicher, dass eine Funktion auch nach Änderungen weiterhin korrekt arbeitet.

Beispiel

Gegeben sei die Funktion:

function y = celsius2fahrenheit(x)
    y = x*9/5 + 32;
end

Frage: Wie kann sichergestellt werden, dass zukünftige Änderungen keine Fehler verursachen?

Antwort: → Automatisierte Unit-Tests.

2. Das MATLAB Unit-Test Framework

MATLAB stellt das Paket

matlab.unittest

bereit.

Tabelle 1: Bestandteile des MATLAB Unit-Test Framework
Element Zweck
TestCase Basisklasse für Tests
verifyEqual Ergebnis prüfen
verifyTrue Wahrheitswert prüfen
verifyError Fehler erwarten
TestSuite Testsammlung
TestRunner Testausführung

3. Erster Test

Zu testende Funktion

function y = quadrat(x)
    y = x.^2;
end

Testklasse

classdef TestQuadrat < matlab.unittest.TestCase
    methods(Test)
        function testPositive(testCase)
            actual = quadrat(4);
            expected = 16;

            testCase.verifyEqual(actual,expected);
        end
    end
end

Test ausführen

results = runtests('TestQuadrat');

Ausgabe:

Running TestQuadrat
.
Done TestQuadrat


4. Mehrere Testfälle

classdef TestQuadrat < matlab.unittest.TestCase
    methods(Test)
        function testPositive(testCase)
            actual = quadrat(4);
            expected = 16;

            testCase.verifyEqual(actual,expected);
        end
    end
end

5. Toleranzen bei Fließkommazahlen

Direkte Vergleiche sind problematisch:

0.1 + 0.2 == 0.3

Daher

actual = sin(pi);
testCase.verifyEqual( ...
    actual,...
    0,...
    'AbsTol',1e-10);

6. Fehler testen

Funktion

function y = wurzel(x)
    if x < 0
        error('MATLAB:NegativeInput',...
              'Nur positive Werte erlaubt')
    end
    y = sqrt(x);
end

Test

function testError(testCase)

    testCase.verifyError( ...
        @() wurzel(-5), ...
        'MATLAB:NegativeInput');

end

7. Parameterisierte Tests

Oft möchte man dieselbe Funktion mit vielen verschiedenen Eingabewerten testen. Ohne parameterisierte Tests müsste man für jeden Fall eine eigene Testmethode schreiben.

Das funktioniert, ist aber:

  • viel Code
  • schlecht wartbar
  • fehleranfällig

Die elegantere Lösung besteht darin die Testdaten als Eigenschaften zu definieren:

classdef TestQuadrat < matlab.unittest.TestCase
    properties(TestParameter)
        x = {0,1,2,3};
        y = {0,1,4,9};
    end

    methods(Test)
        function testQuadrat(testCase,x,y)
            testCase.verifyEqual(quadrat(x),y);
        end
    end
end

Testausführung

results = runtests('TestQuadrat');

Ausgabe:

Running TestQuadrat
....
Done TestQuadrat

8. Testumgebung

Jeder Test soll unter definierten und reproduzierbaren Bedingungen starten.

Typische Vorbereitungen sind:

  • Testdaten laden
  • Dateien erzeugen
  • Verzeichnisse anlegen
  • Hardware initialisieren
  • Parameter setzen
  • Objekte erzeugen

Ohne Fixtures müsste derselbe Vorbereitungscode in jeder Testmethode wiederholt werden.

Beispiel

Angenommen mehrere Tests benötigen dieselbe Abtastrate

fs = 1000; % in Hz

In der Funktion setup wird die Abtastrate definiert.

methods(TestMethodSetup)

    function setup(testCase)
        testCase.TestData.fs = 1000;
    end
end

Testmethode

classdef TestFilter < matlab.unittest.TestCase
    methods(TestMethodSetup)
        function setup(testCase)
            testCase.TestData.fs = 1000;
        end
    end

    methods(Test)
        function testLength(testCase)
            fs = testCase.TestData.fs;
        end

        function testAmplitude(testCase)
            fs = testCase.TestData.fs;
        end
    end
end

Anwendung

fs = testCase.TestData.fs;

Typische Anwendungen:

  • Messdaten laden
  • Simulationsumgebungen vorbereiten
  • Testverzeichnisse anlegen

9. Beispiel aus der Signalverarbeitung

Zu testende Funktion

function y = movingAverage(x)
    y = movmean(x,3);
end

Test

classdef TestMovingAverage ...
        < matlab.unittest.TestCase
    methods(Test)
        function testConstantSignal(testCase)
            x = ones(1,100);
            y = movingAverage(x);
            testCase.verifyEqual(y,x,'AbsTol',1e-12);
        end
    end
end

10. Testbericht

Ein Testbericht ist die strukturierte Ausgabe aller Testergebnisse nach der Ausführung einer Testsuite. Er zeigt nicht nur, ob Tests bestanden wurden, sondern auch welche Tests, warum, wie lange und mit welchem Ergebnis.

In MATLAB erfolgt das über das Unit-Test-Framework MATLAB mit dem TestRunner.

Wenn Sie Tests ausführst, willen Sie typischerweise mehr als nur:

OK / FAILED

Ein Testbericht beantwortet z. B.:

  • Welche Tests wurden ausgeführt?
  • Welche sind bestanden/fehlgeschlagen?
  • Welche Fehler sind aufgetreten?
  • Wie lange hat jeder Test gedauert?
  • Gab es Warnungen oder Abbrüche?

Standard-Testausführung

suite = testsuite(pwd);
results = runtests(suite);

Tipp: pwd ist eine eingebaute MATLAB-Funktion und steht für Print Working Directory. pwd gibt den aktuellen Arbeitsordner zurück, also den Ordner, in dem MATLAB gerade arbeitet.

TestRunner für detaillierte Berichte

Der zentrale Baustein ist der TestRunner

runner = matlab.unittest.TestRunner.withTextOutput;
results = runner.run(suite);
  • TestRunner führt die Tests kontrolliert aus
  • withTextOutput erzeugt eine strukturierte Textausgabe
  • results enthält alle Testergebnisse als Objektliste

Auswertung:

  • Passed
  • Failed
  • Incomplete
  • Duration

Beispiel

Zu testende Funktion

function y = addiere(a,b)
   y = a + b;
end

Testklasse

classdef TestAddiere < matlab.unittest.TestCase
    methods(Test)
        function testPositive(testCase)
            testCase.verifyEqual(addiere(2,3),5);
        end
        function testNegative(testCase)
            testCase.verifyEqual(addiere(-2,-3),-5);
        end
        function testMixed(testCase)
            testCase.verifyEqual(addiere(-2,5),3);
        end
    end
end

Standard-Testausführung

results = runtests('TestAddiere');

Typische Ausgabe im Command Window

Running TestAddiere
...
Done TestAddiere
  • Jeder Punkt . = Test bestanden
  • F = Failed
  • E = Error

Ausgabe als Ergebnisobjekte

results =
 1×3 TestResult array
 Name                  Passed  Failed  Incomplete  Duration
 ____________________  ______  ______  __________  ________
 TestAddiere/testPositive   true   false   false     0.0012
 TestAddiere/testNegative   true   false   false     0.0009
 TestAddiere/testMixed      true   false   false     0.0010

äquivalente Alternative

suite = testsuite('TestAddiere');
results = run(suite);

TestRunner mit Textausgabe

Das ist ein „professioneller Runner“, der einen strukturierten Bericht erzeugt.

import matlab.unittest.TestRunner 
runner = TestRunner.withTextOutput;

Test ausführen

results = runner.run(suite);

Beispielausgabe (detaillierter Bericht)

Running TestAddiere
TestAddiere/testPositive .... PASSED
TestAddiere/testNegative .... PASSED
TestAddiere/testMixed .... PASSED
Done TestAddiere

Praktische Übung

Aufgabe 11.1

Implementieren Sie:

function y = cube(x)

y=x3

Erstellen Sie mindestens drei Unit-Tests.

Aufgabe 2

Entwickeln Sie Tests für:

function y = celsius2fahrenheit(x)

Prüfen Sie:

  • 0 °C
  • 100 °C
  • −40 °C

Aufgabe 3

Aufgabe 4



MATLAB® Befehlsübersicht
→ zurück zum Hauptartikel: BSE Modellierung und Simulation - SoSe26