- 1 Abschnitt
- 9 Lektionen
- Um den Kurs in deinem Profil zu hinterlegen klicke oben auf Starten
Lösungen
Aufgabe 1: Einführung in Modultests
Frage 1: Was sind Modultests und warum sind sie wichtig für die Qualitätssicherung in der Softwareentwicklung? Nenne drei Vorteile von Modultests.
Lösung:
Modultests sind Tests, die einzelne Komponenten oder Einheiten einer Softwareanwendung isoliert überprüfen. Sie sind wichtig für die Qualitätssicherung, da sie helfen, Fehler frühzeitig im Entwicklungsprozess zu erkennen und zu beheben.
Drei Vorteile von Modultests:
- Frühzeitiges Erkennen von Fehlern: Fehler können bereits in frühen Entwicklungsphasen entdeckt und behoben werden.
- Vereinfachte Fehlersuche und -behebung: Da Modultests isolierte Einheiten testen, ist die Identifikation und Behebung von Fehlern einfacher.
- Erhöhung der Codequalität und Wartbarkeit: Modultests fördern die Erstellung von modularisiertem, sauberem und wartbarem Code.
Aufgabe 2: Komponenten eines Modultests
Frage 2: Beschreibe die Hauptkomponenten eines Modultests. Welche Rolle spielen Assertions in einem Modultest?
Lösung:
Hauptkomponenten eines Modultests:
- Testfälle: Einzelne Situationen oder Szenarien, die getestet werden.
- Testmethoden: Funktionen oder Methoden, die die Testfälle implementieren.
- Testdaten: Spezifische Eingaben, die in einem Test verwendet werden.
- Teststubs: Einfache Implementierungen von Funktionen oder Methoden, die Abhängigkeiten simulieren.
- Assertions: Überprüfungen, die sicherstellen, dass das Ergebnis eines Tests dem erwarteten Wert entspricht. Wenn eine Assertion fehlschlägt, wird der Test als fehlgeschlagen markiert.
Aufgabe 3: Werkzeuge und Frameworks für Modultests
Frage 3: Nenne vier Testframeworks für unterschiedliche Programmiersprachen und erläutere kurz deren Hauptmerkmale.
Lösung:
JUnit (Java):
- Hauptmerkmale: Annotationen (@Test, @Before, @After), Assertions (assertEquals, assertTrue), Integration in Build-Tools (Maven, Gradle).
NUnit (.NET):
- Hauptmerkmale: Attribute ([Test], [SetUp], [TearDown]), Assertions (Assert.AreEqual, Assert.IsTrue), Integration in Visual Studio.
pytest (Python):
- Hauptmerkmale: Einfache Testfunktionen, Fixtures zur Wiederverwendung von Setup- und Teardown-Code, erweiterbar durch Plugins.
Mocha (JavaScript):
- Hauptmerkmale: Unterstützung für asynchrone Tests, Integration mit Assertion Libraries (Chai), verschiedene Berichtsformate.
Aufgabe 4: Erstellung von Modultests
Frage 4: Schreibe ein Python-Skript, das eine Funktion zur Addition von zwei Zahlen enthält. Erstelle eine Test-Suite mit mindestens drei Testfällen für diese Funktion und erkläre den Zweck jedes Testfalls.
Lösung:
Code in add.py:
def add(a, b):
return a + b
Tests in test_add.py:
import pytest
from add import add
# Testmethode für die Addition von zwei positiven Zahlen
def test_add_positive_numbers():
assert add(2, 3) == 5
# Testmethode für die Addition von einer positiven und einer negativen Zahl
def test_add_positive_and_negative():
assert add(-1, 1) == 0
# Testmethode für die Addition von Nullwerten
def test_add_zeros():
assert add(0, 0) == 0
if __name__ == "__main__":
pytest.main()
Erklärung der Testfälle:
- test_add_positive_numbers: Überprüft, ob die Funktion zwei positive Zahlen korrekt addiert.
- test_add_positive_and_negative: Überprüft, ob die Funktion eine positive und eine negative Zahl korrekt addiert.
- test_add_zeros: Überprüft, ob die Funktion zwei Nullwerte korrekt addiert.
Aufgabe 5: Durchführung von Modultests
Frage 5: Wie kannst du Modultests in eine CI/CD-Pipeline integrieren? Beschreibe die Schritte und nenne ein Beispiel für eine GitHub Actions-Konfigurationsdatei, die Modultests automatisiert ausführt.
Lösung:
Schritte:
- Erstellen einer CI/CD-Konfigurationsdatei.
- Festlegen der Bedingungen, unter denen die Tests ausgeführt werden sollen (z.B. bei jedem Push oder Merge).
- Installieren der Abhängigkeiten.
- Ausführen der Tests.
- Erstellen eines Testberichts und ggf. Hochladen von Artefakten.
Beispiel für eine GitHub Actions-Konfigurationsdatei:
name: Python application
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
- name: Run tests
run: |
pytest
- name: Upload test results
if: failure()
uses: actions/upload-artifact@v2
with:
name: test-results
path: test-results/
Aufgabe 6: Analyse der Testergebnisse
Frage 6: Wie interpretierst du die Ergebnisse eines Coverage-Berichts? Was bedeutet es, wenn eine bestimmte Zeile in einem Bericht als nicht abgedeckt angezeigt wird?
Lösung:
Ein Coverage-Bericht zeigt, welche Teile des Codes durch Tests abgedeckt sind und welche nicht. Wenn eine bestimmte Zeile als nicht abgedeckt angezeigt wird, bedeutet dies, dass es keine Tests gibt, die diese Zeile ausführen. Dies könnte ein Hinweis darauf sein, dass wichtige Szenarien nicht getestet wurden, und es sollten zusätzliche Tests geschrieben werden, um diese Zeile abzudecken.
Aufgabe 7: Testabdeckung und -metriken
Frage 7: Erkläre, was Testabdeckung ist und warum sie wichtig ist. Nenne zwei Arten der Testabdeckung und beschreibe, wie sie gemessen werden können.
Lösung:
Testabdeckung bezieht sich auf den Prozentsatz des Codes, der durch Tests überprüft wird. Sie ist wichtig, weil sie hilft, ungetestete Bereiche im Code zu identifizieren und sicherzustellen, dass möglichst viele Szenarien abgedeckt sind.
- Statement Coverage (Anweisungsabdeckung): Misst den Prozentsatz der ausgeführten Anweisungen im Code. Gemessen durch Tools wie
coverage.py. - Branch Coverage (Zweigabdeckung): Misst den Prozentsatz der ausgeführten Codezweige, z.B. in if/else-Strukturen. Gemessen durch Tools wie
JaCoCo.
Aufgabe 8: Debugging und Fehlerbehebung
Frage 8: Beschreibe zwei Debugging-Techniken, die du verwenden kannst, um die Ursache eines fehlschlagenden Modultests zu identifizieren und zu beheben.
Lösung:
- Debugging-Ausgaben hinzufügen: Durch das Einfügen von Print-Anweisungen oder Logging-Ausgaben im Code kann man den Programmfluss und die Werte von Variablen überprüfen, um die Ursache eines Fehlers zu identifizieren.
- Debugger verwenden: Ein Debugger ermöglicht das Setzen von Breakpoints und das schrittweise Durchlaufen des Codes, um die genaue Stelle und Ursache des Fehlers zu finden.
Aufgabe 9: Grenz- und Sonderfälle
Frage 9: Warum ist es wichtig, Grenz- und Sonderfälle in Modultests zu berücksichtigen? Gib ein Beispiel für einen Grenzfall und einen Sonderfall in einer Funktion, die das Maximum von zwei Zahlen berechnet.
Lösung:
Grenz- und Sonderfälle sind wichtig, um die Robustheit und Stabilität des Codes unter extremen oder unvorhergesehenen Bedingungen zu überprüfen.
- Grenzfall: Berechnung des Maximums von zwei gleichen Zahlen (z.B. max(2, 2)).
- Sonderfall: Behandlung von Nullwerten (z.B. max(0, -1)).
