4.8 KiB
4.8 KiB
5.4 Testverfahren
Softwaretests - Grundlagen
Warum testen?
Testziele
├── Fehler finden
├── Qualität sichern
├── Vertrauen schaffen
├── Risiken minimieren
└── Dokumentation
Testprinzipien
Grundsätze des Testens
├── Vollständig unmöglich → 100% Test nicht möglich
├── Frühzeitig → Tests von Anfang an
├── Defektclustering → Fehler häufen sich
├── Pestizid-Paradox → Tests wiederholen
├── Fehlerfreiheitsirrtum → Keine Fehler ≠ Qualität
└── Kontextabhängig → Projektabhängig
Testarten
Nach Sichtweise
| Testart | Beschreibung |
|---|---|
| White Box | Inneres bekannt, strukturbasiert |
| Black Box | Inneres unbekannt, funktional |
| Gray Box | Teilweise bekannt |
Nach Zeitpunkt
Testphasen
├── Statische Tests (vor Ausführung)
│ └── Code-Review, Analyse
└── Dynamische Tests (bei Ausführung)
└── Unit, Integration, System, Abnahme
Teststufen
Pyramide
Testpyramide
╱╲
╱ ╲ End-to-End (wenige)
╱────╲
╱ ╲ Integration (mittel)
╱────────╲
╱ ╲ Unit-Tests (viele)
╱────────────╲
Unit Tests
Test einzelner Funktionen/Klassen
import unittest
class TestRechner(unittest.TestCase):
def test_addition(self):
ergebnis = addieren(2, 3)
self.assertEqual(ergebnis, 5)
def test_division_durch_null(self):
with self.assertRaises(ZeroDivisionError):
dividieren(10, 0)
if __name__ == '__main__':
unittest.main()
Integrationstests
Test der Zusammenarbeit von Komponenten
Integration - Strategien
├── Big Bang → Alles gleichzeitig
├── Top-Down → Oberste Ebene zuerst
├── Bottom-Up → Unterste Ebene zuerst
└── Sandwich → Beide Richtungen
Systemtests
Test des gesamten Systems
Systemtest - Prüfbereiche
├── Funktionale Anforderungen
├── Nicht-funktionale Anforderungen
├── Schnittstellen
├── Datenintegration
└── Performance
Abnahmetests
Test durch den Kunden
Abnahmetest - Arten
├── Alpha (beim Hersteller)
├── Beta (bei Anwendern)
└── Operational (im Echtbetrieb)
Testmethoden
Black-Box-Tests
Techniken
├── Äquivalenzklassen
├── Grenzwertanalyse
├── Entscheidungstabellen
├── Zustandsübergänge
└── Anwendungsfall-basiert
Äquivalenzklassen
Beispiel: Alterseingabe (0-120)
Gültige Klasse: 0 bis 120
Ungültige Klassen: < 0, > 120
Testfälle:
- 25 (gültig)
- 0 (Grenzwert)
- 120 (Grenzwert)
- -1 (ungültig)
- 121 (ungültig)
White-Box-Tests
Techniken
├── Anweisungsabdeckung
├── Zweigabdeckung
├── Pfadabdeckung
└── Bedingungsabdeckung
Testmanagement
Testplan
# Testplan - [Projekt]
## 1. Testobjekt
[Was wird getestet]
## 2. Testumgebung
[System, Tools]
## 3. Testfälle
| ID | Beschreibung | Erwartung |
|----|--------------|-----------|
| T1 | Login gültig | Erfolg |
| T2 | Login ungültig | Fehler |
## 4. Zeitplan
[Termine]
## 5. Kriterien
[Abnahme]
Testfall-Struktur
Testfall - Elemente
├── Testfall-ID
├── Titel/Beschreibung
├── Vorbedingungen
├── Testschritte
├── Erwartetes Ergebnis
├── Tatsächliches Ergebnis
├── Status (Pass/Fail)
└── Tester
Testautomatisierung
Werkzeuge
| Zweck | Tools |
|---|---|
| Unit Tests | JUnit (Java), pytest (Python), NUnit (.NET) |
| UI Tests | Selenium, Playwright, Cypress |
| API Tests | Postman, RestAssured |
| Lasttests | JMeter, k6 |
Beispiel: pytest
# test_calculator.py
import pytest
def test_addition():
assert add(2, 3) == 5
def test_subtraktion():
assert sub(5, 3) == 2
@pytest.mark.parametrize("a,b,expected", [
(1, 1, 2),
(0, 0, 0),
(-1, 1, 0),
])
def test_add_param(a, b, expected):
assert add(a, b) == expected
Fehlermanagement
Fehlerverfolgung
Fehlerlebenszyklus
Neu → Bestätigt → In Bearbeitung → Gelöst → Geschlossen
↓
Abgelehnt
Fehlerprioritäten
| Priorität | Beschreibung | Reaktionszeit |
|---|---|---|
| Kritisch | System nicht nutzbar | Sofort |
| Hoch | Wichtige Funktion | 24h |
| Mittel | Kleinere Probleme | 1 Woche |
| Niedrig | kosmetisch | Bei Zeit |
Querverweise
Stand: 2024