5 - Testen III: Test Doubles, Fehlermuster, Refactoring

Test Doubles

Problem bei Komponententests

Man kann sie nicht leicht isoliert vom restlichen System Testen weil:

sie miteinander interagieren, andere Schnittstellen aufrufen wie zB die Datenbank

nicht deterministische Werte nutzen wie zB Systemzeit

Test doubles

= Generischer Begriff für Austausch von realen Komponente des Systems durch eine alternative, meist simplifizierte Implementierung für Testzwecke.

Wir möchten Abhängigkeiten zwischen Komponenten ausblenden.

Komponenten mit einfacheren “doubles” ersetzen zum Testen.

Vorteile: Isolation, Keine Abhängigkeiten, geringere Komplexität, Reduktion der Ausführungszeit.

Test Double Typen

Dummy Object

Nicht zum Testen

Nicht zum Verwenden, nicht ausführbar


Quasi “leeres” Argument - Platzhalter ohne Funktionalität

zBDummyCustomerKlasse implementiertICustomeraber wirftNotImplementedException

Fake Object

Nicht zum Testen

Zum Verwenden, ausführbare Implementierung


Wenn reale Implementierung zu langsam oder nicht verfügbar

zB simulierte Datenquelle, In-Memory Datenbank → keien Echtdaten

Stub

Zum Testen

Zum Verwenden, ausführbare Implementierung


Liefert vordefinierte Werte, Exceptions indem Pfad vorbestimmt wird.

Erlaubt Testen von Pfaden die von außen nicht beeinflusst und durchlaufen werden können.

  • Beispiel: Asynchrone Abfrage an einem Server

    Original

    Stub

Mock

Gleich wie Stub, aber die Parameter die an Mock gegeben werden, werden auch im Test überprüft.

Mock erkennt wenn unerwartete Werte erhalten werden - Assertion und Exception.

  • Fortsetzung Beispiel: Asynchrone Abfrage an einem Server

    Mock - Version 1: Ohne Assertions

    Mock - Version 2: Mit Assertions

Spy

Proxy Objekt - Einzelne Methoden durch andere Implementierung ersetzt.

Mocking Frameworks

Mocking Frameworks

vereinfachen Verwendung für Mocks: Unterstützen Erstellung, Konfiguration, Überprüfung

zB Mockito, JMockit, EasyMock, PowerMock, ...

Statische code Analyse (toolgestützt)

toolgestützte Code Analysen für statische QS-Methoden:

Tools: FindBugs/SpotBugs, SonarLint, SonarQube

Statische Code Analyse / Fehlermuster

Verbessert Code Qualität, Wartbarkeit, reduziert Fehler

Häufige Fehlermuster im Code finden wie:

• Variablen mit undefiniertem Wert • Komplexe Konstrukte • Toter Code • Potenzielle Endlosschleifen • Security Schwachstellen • Unused Code • …

Regeln eingeteilt in:

• Bug Potenzielle Fehler • Vulnerability Sicherheitslücken • Code Smell Unschöner/unwartbarer Code

Refactoring

Motivation

Design “verwahrlost” mit der Zeit

Bad Smells zeigen das Refactoring notwendig ist

“Technische Schuld”: Design vernachlässigt um kurz effizienter zu sein

Refactoring

Code Struktur ändern für bessere:

Lesbarkeit, Verständlichkeit, interne Architektur/Design

Funktionalität, Fehler bleiben gleich

Ziel ist es nicht die Performance zu verbessern


Klare Struktur durch Kapselung, Lesbarkeit:

Leichtere Einarbeitung von neuen Entwicklern

Bessere Wartbarkeit, Anpassbarkeit, Erweiterbarkeit

Geringerer Aufwand beim Testen, Leichtere Identifikation von Fehlern

Vorgehensweise

  1. Identifikation Stelle im Code manuell oder mit Tool finden
  1. Testabdeckung Sicherstellen, dass die Stelle abgedeckt ist
  1. Durchführung umbauen, testen (Funktionalität bleibt gleich)

    Patterns als allgemeine Lösungen für widerkehrende Probleme

Bad Smells

Kennzeichen von schlechten Designs - zeigen wo Refactoring notwendig ist.

Beispiele (nach Martin Fowler):

• Duplicated Code • Long Method • Large Class • Long Parameter List • Shotgut Surgery: Kleine Änderungen am Code führen zu Anpassungen in vielen Klassen • Feature Envy: Eine andere Klasse hat mehr Nutzen für eine Funktion • …

Patterns

Allgemeine Lösungen für wiederkehrende Probleme (Bad Smells)

Unterteilung in Gruppen:

• Composing Methods • Moving Features Between Objects • Organizing Data • Simplifying Conditional Expressions • Simplifying Method Calls • Dealing With Generalization