Teststufen und -arten

In dieser Lerneinheit entdeckst du die verschiedenen Teststufen wie Unit-, Integrations- und Systemtests sowie deren spezifische Einsatzgebiete in der Softwareentwicklung. Du lernst die Unterschiede zwischen funktionalen und nicht-funktionalen Tests kennen und verstehst, wann welche Testart am sinnvollsten einzusetzen ist. Das Wissen ermöglicht dir, passende Teststrategien für deine Entwicklungsprojekte auszuwählen und systematisch umzusetzen.

Einführung

Du hast deine Methode geschrieben und einen Test dafür erstellt. Der Test ist grün. Aber was, wenn diese Methode mit einer Datenbank kommuniziert? Was, wenn das gesamte System unter Last steht? Und was sagt eigentlich der Kunde dazu?

Ein einziger Testtyp reicht nicht aus, um Softwarequalität zu garantieren. Unterschiedliche Fehler zeigen sich erst auf unterschiedlichen Ebenen.

In dieser Lerneinheit erfährst du, welche Teststufen es gibt, wann du welche einsetzt und wie du von der einzelnen Komponente bis zur Kundenabnahme testest.

Lernziele

Nach dieser Lerneinheit kannst du:

  • Unit-Tests und ihre Vorteile erklären
  • Die Integrationsstrategien Big Bang, Top-Down und Bottom-Up unterscheiden
  • System-Tests und Acceptance-Tests voneinander abgrenzen
  • Funktionale und nicht-funktionale Tests unterscheiden und Beispiele nennen

Überleitung

In der Softwareentwicklung gibt es verschiedene Teststufen, die aufeinander aufbauen. Jede Stufe prüft andere Aspekte der Software.

Schauen wir uns die Teststufen genauer an.

Was ist ein Unit-Test?

Unit-Tests prüfen die kleinsten testbaren Teile einer Anwendung isoliert. Das sind typischerweise einzelne Methoden oder Funktionen.

Unit-Tests laufen unabhängig von externen Ressourcen wie Datenbanken. Sie liefern sofortige Rückmeldung über den Code-Status.

Ein Beispiel: Du testest, ob eine add()-Methode bei Eingabe von 2 und 3 tatsächlich 5 zurückgibt.

Warum Unit-Tests?

Fehlerfrüherkennung

Unit-Tests finden Logikfehler früh im Entwicklungszyklus. Du merkst sofort, wenn eine Änderung etwas kaputt macht.

Warum Unit-Tests?

Dokumentation und Refactoring-Sicherheit

Unit-Tests dokumentieren, was eine Funktion leisten soll. Beim Refactoring hast du ein Sicherheitsnetz: Wenn die Tests grün bleiben, funktioniert der Code noch wie erwartet.

Unit-Test in der Praxis

Beispiel in JUnit 5

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
 
class CalculatorTest {
    @Test
    void addShouldReturnSum() {
        Calculator calc = new Calculator();
        assertEquals(5, calc.add(2, 3));
    }
}

Erklärung des Codes

  • @Test markiert die Methode als Testfall
  • assertEquals(expected, actual) prüft, ob das Ergebnis stimmt
  • Der Testname beschreibt das erwartete Verhalten

Was ist ein Integration-Test?

Integration-Tests prüfen das Zusammenspiel mehrerer Komponenten. Sie finden Fehler, die Unit-Tests nicht erkennen können:

  • Interface-Fehler: Die Methode existiert, aber die Parameter passen nicht
  • Datenflussprobleme: Daten werden falsch zwischen Modulen übergeben
  • Datenbankzugriffsfehler: Die Queries funktionieren, aber nicht mit echten Daten

Integrationsstrategien

Big Bang

Alle Module werden auf einmal integriert und getestet. Das ist schnell, aber wenn Fehler auftreten, sind sie schwer zu lokalisieren.

Integrationsstrategien

Top-Down und Bottom-Up

  • Top-Down: Du beginnst beim Hauptmodul und integrierst schrittweise die Untermodule. Du brauchst Stubs für noch nicht implementierte Teile.
  • Bottom-Up: Du beginnst bei den Untermodulen und arbeitest dich nach oben. Keine Stubs nötig, aber späte UI-Tests.

In der Praxis wird oft inkrementell integriert, da Fehler so leichter lokalisierbar sind.

Integration-Test in der Praxis

Beispiel: Service mit Repository

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
 
class UserServiceIntegrationTest {
    @Test
    void shouldSaveAndRetrieveUser() {
        UserRepository repo = new UserRepository();
        UserService service = new UserService(repo);
 
        User user = new User("Max", "max@test.de");
        service.save(user);
 
        User found = service.findByEmail("max@test.de");
        assertEquals("Max", found.getName());
    }
}

Erklärung des Codes

  • Der Test prüft das Zusammenspiel von UserService und UserRepository
  • Es wird eine echte Repository-Instanz verwendet, keine Mock-Objekte
  • Der Test verifiziert den kompletten Datenfluss: Speichern und Abrufen
⏳ Lädt Dataview-Inhalt...

Was ist ein System-Test?

System-Tests prüfen das vollständig integrierte System gegen seine Anforderungen. Im Gegensatz zu Unit- und Integration-Tests wird hier das komplette System als Ganzes getestet.

Bei System-Tests wird meist Black-Box-Testing angewendet: Du prüfst das Verhalten, ohne den internen Code zu kennen.

Arten von System-Tests

Typische System-Tests:

  • Leistungstest: Wie verhält sich das System unter Last?
  • Sicherheitstest: Ist das System vor Angriffen geschützt?
  • Usability-Test: Ist die Anwendung benutzerfreundlich?
  • Kompatibilitätstest: Funktioniert die Software in verschiedenen Umgebungen?

System-Test in der Praxis

Beispiel: E2E-Test mit Playwright

import { test, expect } from "@playwright/test";
 
test("Benutzer kann sich einloggen", async ({ page }) => {
    await page.goto("https://app.example.com/login");
 
    await page.fill("#email", "test@example.com");
    await page.fill("#password", "geheim123");
    await page.click("button[type=submit]");
 
    await expect(page).toHaveURL("/dashboard");
    await expect(page.locator("h1")).toContainText("Willkommen");
});

Erklärung des Codes

  • Der Test simuliert einen echten Benutzer im Browser
  • Er prüft den kompletten Login-Flow vom Frontend bis zur Datenbank
  • expect() verifiziert das erwartete Verhalten der gesamten Anwendung

Was ist ein Acceptance-Test?

Acceptance-Tests (User Acceptance Tests, UAT) sind die letzte Hürde vor dem Go-Live. Der Kunde oder Endnutzer testet die Software unter realen Bedingungen.

Ziel: Verifizieren, dass die Software die Geschäftsanforderungen erfüllt und für den produktiven Einsatz bereit ist.

Typen von Acceptance-Tests

Es gibt verschiedene Formen:

  • Alpha-Test: Interner Test vor dem Beta-Release
  • Beta-Test: Test durch echte Nutzer unter realen Bedingungen
  • Contract Acceptance: Prüfung gegen vertragliche Vereinbarungen
  • Regulation Acceptance: Einhaltung gesetzlicher Standards (z.B. DSGVO)

Acceptance-Test in der Praxis

Beispiel: BDD mit Gherkin-Syntax

Feature: Warenkorb
  Als Kunde
  möchte ich Produkte in den Warenkorb legen
  damit ich sie kaufen kann
 
  Scenario: Produkt hinzufügen
    Given ich bin auf der Produktseite "Laptop"
    When ich auf "In den Warenkorb" klicke
    Then enthält mein Warenkorb 1 Artikel
    And der Gesamtpreis beträgt 999 Euro

Erklärung des Codes

  • Gherkin beschreibt Tests in natürlicher Sprache
  • Der Kunde kann die Szenarien lesen und validieren
  • Tools wie Cucumber führen diese Beschreibungen als automatisierte Tests aus

Funktionale Tests

Funktionale Tests prüfen, ob die Software ihre spezifizierten Funktionen korrekt ausführt.

Beispiele:

  • Smoke-Test: Funktionieren die Kernfunktionen nach einem Build?
  • Regressionstest: Haben Änderungen bestehende Funktionen beschädigt?
  • Boundary-Test: Wie verhält sich die Software an Wertgrenzen?

Nicht-funktionale Tests

Nicht-funktionale Tests bewerten Qualitätsattribute wie Performance, Sicherheit und Benutzerfreundlichkeit.

Beispiele:

  • Performance-Test: Wie schnell reagiert die Anwendung?
  • Security-Test: Welche Sicherheitslücken gibt es?
  • Compatibility-Test: Läuft die Software auf verschiedenen Plattformen?

Werkzeuge in der Praxis

Für verschiedene Testarten gibt es spezialisierte Tools:

  • Unit-Tests: JUnit 5 (Java), pytest (Python), Jest (JavaScript)
  • UI-Automatisierung: Selenium WebDriver, Playwright, Cypress
  • Performance: Apache JMeter, k6
  • Security: OWASP ZAP, Burp Suite

Viele Teams kombinieren diese Tools in CI/CD-Pipelines für automatisierte Tests.

⏳ Lädt Dataview-Inhalt...

Zusammenfassung

Zusammenfassung:

Teststufen im Überblick

Software wird auf verschiedenen Ebenen getestet, die aufeinander aufbauen.

  • Unit-Tests prüfen einzelne Methoden isoliert und liefern schnelles Feedback.
  • Integration-Tests verifizieren das Zusammenspiel mehrerer Komponenten.
  • System-Tests testen das komplette System gegen alle Anforderungen.
  • Acceptance-Tests validieren die Software aus Kundensicht vor dem Go-Live.

Integrationsstrategien

Beim Zusammenführen von Modulen gibt es verschiedene Ansätze.

  • Big Bang: Alles auf einmal integrieren, schnell aber schwer zu debuggen.
  • Top-Down: Vom Hauptmodul zu Untermodulen, erfordert Stubs.
  • Bottom-Up: Von Untermodulen nach oben, keine Stubs nötig.

Funktionale vs. nicht-funktionale Tests

Tests lassen sich nach ihrem Fokus unterscheiden.

  • Funktionale Tests: Prüfen die korrekte Umsetzung der Anforderungen (Smoke, Regression, Boundary).
  • Nicht-funktionale Tests: Bewerten Qualitätsattribute wie Performance, Sicherheit und Usability.

Werkzeuge in der Praxis

Für verschiedene Teststufen gibt es spezialisierte Tools.

  • Unit-Tests: JUnit 5, pytest, Jest
  • UI-Automatisierung: Playwright, Cypress, Selenium
  • Performance: JMeter, k6
  • Security: OWASP ZAP, Burp Suite

Ausblick:

In der nächsten Lerneinheit beschäftigst du dich mit Testverfahren und -techniken. Du lernst den Unterschied zwischen Black-Box- und White-Box-Testing kennen und verstehst, wann du welche Technik einsetzt. Ausserdem erfährst du, wie du mit Äquivalenzklassen und Grenzwertanalyse systematisch Testfälle ableitest.