197 lines
7.5 KiB
Markdown
197 lines
7.5 KiB
Markdown
# 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](01_ImplementingForMaintainability.md#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](01_ImplementingForMaintainability.md#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
|
|
|
|
- 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](#black-box-testing) testen von größeren Softwareteilen
|
|
- _bspw. Komponenten, Services_
|
|
- **Unit Tests**
|
|
- werden während Entwicklung von Developern geschrieben
|
|
- 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)
|
|

|
|
1. Tests schreiben
|
|
- **Design**
|
|
- Akzeptanzkriterien für den nächsten Arbeitsschritt festlegen
|
|
- Anregung [lose gekoppelte Komponenten](ImplementingForMaintainability.md#loose-coupling) zu entwerfen
|
|
- einfache Testbarkeit, dann verbinden
|
|
- Ausführbare Beschreibung von dem was der Code tut
|
|
- **Implementierung**
|
|
- Vervollständigen einer regressiven Test-Suite
|
|
2. Tests ausführen
|
|
- **Implementierung**
|
|
- Error erkennen, während der Kontext noch frisch ist
|
|
- **Design**
|
|
- Bewusstmachung, wann die Implementierung vollständig ist
|
|
|
|
> 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
|
|
- 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
|