7.5 KiB
7.5 KiB
Implementing for Maintainability
Motivation and Introduction
- Unit und Integration Testing ist ein bekannter Ansatz um Qualität sicherzustellen
- Gut-getestete Anwendungen:
- 1 line of code = 1-3 lines of test code
- kann auf bis zu 1:10 hochgehen
- Produkt- und Testcode werden parallel geschrieben
- guten Code schreiben ist schwer
Black-/White-Box Testing
Black-Box-Testing
Nur das Interface ist bekannt, nicht der Inhalt
- Methode vom Software-Testing, das die Funktion analysiert, ohne den Mechanismus zu kennen
- Normalerweise rund um die Spezifikationen und Anforderungen
- Was soll die Anwendung tun, nicht wie tut sie es
White-Box-Testing
Das Interface und alle Mechanismen sind bekannt
- Testmethodik, die verifiziert, wie die Anwendung arbeitet
- Tests sind am Sourcecode ausgerichtet, nicht an den Anforderungen
Pros / Cons
- White-Box-Testing ist systematischer und anspruchsvoller
- Analyse des Codes kann zu Fehlerentdeckungen führen, die zuvor übersehen wurden
- Testergebnisse sind oft spröde
- Sind sehr verknüpft mit der Implementierung des Codes
- Solche Tests produzieren viele false-positives und sind nicht gut für die Metrik der Resistenz gegen Refactoring
- Können häufig nicht rückgeschlossen werden zu einem Verhalten, dass wichtig ist für eine Business-Person
- Starkes Zeichen, dass die Tests nicht viel Wert hinzufügen
- Black-Box-Testing hat gegensätzliche Vor-/Nachteile
Black-/White-Box-Testing sind Konzepte, die auf verschiedene Test-Typen angewendet werden können
Testing Quadrants Matrix
Quadrant 1: Technologie-fokussierte Tests, die das Development leiten
-
Developer Tests:
- Unit tests
- Verifizieren Funktionalität eines kleinen Subsets des Systems
- Component-/Integration Tests:
- Verifizieren Verhalten eines größeren Teils
- Unit tests
-
Tests sind nicht für den Kunden
Unit Testing
- Unit Tests sind die essenzielle Basis einer guten Test-Suite
- Verglichen mit anderen, sind sie einfach zu erstellen und warten
- Viele Unit-Tests :)
Goals of Testing during Implementation
Aktiviere nachhaltiges Wachstum des Software-Projekts
- Nachhaltigkeit ist wichtig
- Projektwachstum ist am Anfang einfach
- Das Wachstum zu halten ist schwer
- Tests können das nachhaltige Wachstum fördern
- Aber: erfordern initialen, teilweise signifikanten Einsatz
- Schlechte Tests bringen nichts
- verlangsamen am Anfang schlechten Code
- langfristig trotzdem ungünstig
- Test Code ist Teil der Codebase
- Teil, der ein spezifisches Problem behandelt - Anwendungsrichtigkeit sicherstellen
- Kosten eines Tests
- Wert
- anstehende Kosten
- Refactoring des Tests, wenn der Code refactored wird
- Test bei jeder Codeänderung ausführen
- Mit Fehlalarmen durch den Test umgehen
- Zeit für das Verstehen des Tests, wenn man den zu testenden Code verstehen möchte
General Testing Strategy
Testing Automation Pyramid
- Software Tests in 3 Kategorien aufteilen
- UI-Tests
- Testen die Anwendung durch Interaktion mit der UI
- sehr high-level
- Service Tests
- Black-Box testen von größeren Softwareteilen
- bspw. Komponenten, Services
- Black-Box testen von größeren Softwareteilen
- Unit Tests
- werden während Entwicklung von Developern geschrieben
- UI-Tests
- Gibt Idee, wie viele Tests pro Kategorie in der Test-Suite sein sollten
Testing Ice Cream Cone
- Style einer Test-Suite, die häufig in der Industrie verwendet wird
- hohe Anzahl manueller, high-level Tests
- end-to-end Tests (auch an UI), die automatisch ausgeführt werden können
- nur wenige integration/unit tests
- Tests Suite mit dieser Strategie ist nicht gut wartbar
- manuelle Tests sind teuer und langwierig
- automatisierte high-level Tests gehen häufig kaputt, sobald Änderungen in der Anwendung auftreten
Test Driven Development (TDD)
- Tests schreiben
- Design
- Akzeptanzkriterien für den nächsten Arbeitsschritt festlegen
- Anregung lose gekoppelte Komponenten zu entwerfen
- einfache Testbarkeit, dann verbinden
- Ausführbare Beschreibung von dem was der Code tut
- Implementierung
- Vervollständigen einer regressiven Test-Suite
- Design
- Tests ausführen
- Implementierung
- Error erkennen, während der Kontext noch frisch ist
- Design
- Bewusstmachung, wann die Implementierung vollständig ist
- Implementierung
Golden Rule of TDD: schreibe niemals neue Funktionalitäten ohne einen fehlschlagenden Test
Vorteile des TDD
- signifikante Reduktion der Defekt-Rate
- auf Kosten eines moderaten Anstiegs im initialen Development-Prozesses
- Empirische Untersuchungen haben das noch nicht bestätigt
- TDD hat aber zu Qualitätssteigerung des Codes geführt
Häufige Fehler beim TDD
- Individuelle Fehler
- Vergessen die Tests regelmäßig auszuführen
- Zu viele Tests auf einmal schreiben
- Zu große/grobe Tests schreiben
- zu triviale Tests schreiben, die eh funktionieren
- Team-Fehler
- Nur partieller Einsatz
- Schlechte Wartung der Test-Suite
- Verlassene Test-Suite (nie ausgeführt)
Unit-Testing vs. Integration Testing
Unit | Integration |
---|---|
kleiner Teil eines Verhaltens | größere Portion Code |
4 Typen von Produktions-Code
Dimensionen
Komplexität und Domain-Signifikanz
- Code Komplexität
- Definiert durch Nummer der Branching-Punkte im Code
- if-statements, Polymorphismus
- Domain-Signifikanz
- Wie signifikant ist der Code für die problematische Domain
- normalerweise Verbindung Domain-Layer-Code zu End-User-Ziele
- Hohe Domain-Signifikanz
- Bsp. für niedrige Relevanz: Utility Code
Nummer der Kollaborateure
- Kollaborateur = Abhängigkeit, die veränderlich /& außerhalb des Prozesses ist
- veränderlich
- nicht nur read-only
- außerhalb des Prozesses
- häufig geteilt
- hindert Tests an unabhängiger Ausführung
- veränderlich
- Code mit vielen Kollaborateuren ist schwer zu testen
Typen
Domain model & algorithms
- Domain Code, wenige Kollaborateure
- komplexer Code häufig Teil des Domain-Models
- wenige Kollaborateure → Testbarkeit
- sollte NIEMALS Abhängigkeiten außerhalb des Prozesses haben
Controllers
- Wenig Domain Code, viele Kollaborateure
- Koordination der Ausführung von Use-Cases für Domain-Klassen und externen Anwendungen
- Keine komplexe / Business-kritische Arbeit selbst/allein machen
- wenig Komplexität, wenig Domain-Signifikanz
- Viele Abhängigkeiten außerhalb des Projekts
Overcomplicated Code
- Viel Domain Code, viele Kollaborateure
- ist aber auch komplex und wichtig
Trivialer Code
- wenig Domain-Code, wenig Kollaborateure
Separierung von Controllers & DomainModel, Algorithmen
- Separiert komplexen Code von Code, der Orchestrierung macht
- Domain Code hat tiefe Implementierung in Business Logik
- Controller haben breite Orchestrierung aber enge Komplexität
- Erhöht Wartbarkeit und Testbarkeit
Wie testet man die 4 Typen?
- trivialer Code muss nicht getestet werden