Zurück zum Blog
Clean Code März 2026 8 Min Lesezeit

Clean Code #7: Testing — Tests als Qualitätsgarantie

MN

Michael Nikolaus

Vorstand & Softwarearchitekt, Minicon eG

Code ohne Tests ist per Definition Legacy-Code. Tests geben Ihnen die Freiheit, Code zu ändern, ohne Angst zu haben, etwas kaputt zu machen. Sie sind das Sicherheitsnetz professioneller Entwicklung.

Die drei Gesetze von TDD

Test-Driven Development folgt einem einfachen Zyklus:

  1. •Red: Schreiben Sie einen fehlschlagenden Test
  2. •Green: Schreiben Sie den minimalen Code, der den Test bestehen lässt
  3. •Refactor: Verbessern Sie den Code, ohne die Tests zu brechen

Dieses Muster führt zu Code, der von Anfang an testbar designed ist — statt nachträglich "irgendwie" getestet wird.

F.I.R.S.T. — Eigenschaften guter Tests

  • •Fast: Tests müssen schnell laufen — Sekunden, nicht Minuten
  • •Independent: Kein Test darf von einem anderen abhängen
  • •Repeatable: Gleiche Eingabe → gleiches Ergebnis, immer
  • •Self-Validating: Bestanden oder nicht — keine manuelle Prüfung
  • •Timely: Tests werden vor oder mit dem Code geschrieben, nicht Wochen später

Anatomie eines guten Tests

// ✅ Arrange-Act-Assert Muster
[Fact]
public void CalculateTotal_WithTwoItems_ReturnsCorrectSum()
{
    // Arrange
    var cart = new ShoppingCart();
    cart.Add(new Product("Laptop", 999.00m));
    cart.Add(new Product("Mouse", 29.99m));

    // Act
    var total = cart.CalculateTotal();

    // Assert
    Assert.Equal(1028.99m, total);
}

Gute Testnamen

Ein Testname sollte beschreiben: Was wird getestet, unter welchen Bedingungen, und was wird erwartet.

// ❌ Nichtssagend
void Test1() { ... }
void TestCalculation() { ... }

// ✅ Beschreibend
void Discount_WhenCustomerIsPremium_Returns20Percent() { ... }
void Login_WithExpiredToken_ThrowsAuthException() { ... }
void Order_WithEmptyCart_IsRejected() { ... }

Die Test-Pyramide

Die bewährte Verteilung von Tests:

  • •Unit Tests (70%): Schnell, isoliert, testen einzelne Klassen/Methoden
  • •Integration Tests (20%): Testen das Zusammenspiel von Komponenten
  • •End-to-End Tests (10%): Testen den kompletten Workflow

Je weiter oben in der Pyramide, desto langsamer und fragiler die Tests — deshalb weniger davon.

Was testen?

Testen Sie Verhalten, nicht Implementierung. Ein Test sollte prüfen, was eine Methode tut, nicht wie. Wenn Sie interne Implementierungsdetails testen, brechen Tests bei jedem Refactoring.

// ❌ Testet Implementierung
// "Prüfe ob _repository.Save() genau 1x aufgerufen wurde"
_mockRepo.Verify(r => r.Save(It.IsAny<Order>()), Times.Once);

// ✅ Testet Verhalten
// "Prüfe ob die Order nach dem Speichern abrufbar ist"
var saved = await _service.GetOrder(orderId);
Assert.Equal(expectedTotal, saved.Total);

Code Coverage — die richtige Perspektive

80% Code Coverage ist ein gutes Ziel. 100% ist meist Zeitverschwendung — Getter, Setter und triviale Konstruktoren zu testen bringt keinen Mehrwert. Fokussieren Sie sich auf Business-Logik, Edge-Cases und Fehlerszenarien.

Fazit

Tests sind keine optionale Zugabe — sie sind integraler Bestandteil professioneller Softwareentwicklung. Sie ermöglichen Refactoring, dokumentieren Verhalten und geben Ihnen die Zuversicht, dass Ihre Software korrekt funktioniert.

Nächster Artikel: Clean Code #8: Code Reviews — Das Vier-Augen-Prinzip

Passend dazu: Softwareentwicklung in Dahn und der Südwestpfalz

Interesse geweckt?

Lassen Sie uns über Ihr Projekt sprechen

Das erste Gespräch ist kostenlos. Wir hören Ihnen zu und finden die beste Lösung für Sie.

Kontakt aufnehmen