Einführung in Software Testen Flashcards
Qualitätsmetriken
Quantifizieren verschiedene Aspekte der Qualität.
Werden von Tools berechnet.
Beispiele: Lines of Code, Number of Statements, Coverage
Statische Analysen
Werden von Tools unterstützt.
Zum finden von Fehlermustern, Analyse der Systemarchitektur, Überprüfung von Sourcecode Konventionen & Testabdeckung.
Fehlermuster: Beispiele und Vorteile wenn man diese Ausfindig macht
Beispiele: Variablen mit undefiniertem Wert, Toter Code, Potenzielle Endlosschleifen, Komplexe Konstrukte, Security Schwachstelle, etc.
Vorteile: Verbesserung der Code Qualität (Wartbarkeit), Fehler finden, Vermeidung/Reduktion zukünftiger Fehler.
Coding Conventions
Definieren Guidelines für eine spezifische Programmiersprache.
Sorgt für einheitlichen Stil innerhalb eines Projekts- erhöht Lesbarkeit und Verständlichkeit.
Einhaltung überpruft mittels Checkstyle.
Checkstyle
Was wird überprüft? Wie wird es eingesetzt?
Checkstyle Regeln können je nach Projekt angepasst werden.
Üblicherweise beinhaltet Checkstyle:
JavaDoc (Existenz, Struktur)
Naming Conventions (Länge, Zeichen, Format)
Block Checks (Klammernsetzung)
Imports
Size (Anzahl Zeilen, Länge Zeilen, Anzahl Parameter)
Überprüft mittels Maven in den build prozess integriert, oder mittels Plugins in IDE
Commit Conventions
Warum? Was macht eine gute Commit Message aus?
Drei wichtige Gründe: Beschleunigt Review Prozess, Erhöht Wartbarkeit, Unterstützen Erstellung von Release Notes.
Eine gute Commit Message besagt was geändert wurde, warum diese änderung gemacht wurde. Soll immer nur eine Änderung pro Commit sein. Idempotent (in sich geschlossen).
JUnit Best Practices
4 Punkte
- Testfälle isoliert. Jeder Test testet nur einen Aspekt/Zustand. Keine Abhängigkeiten zwischen Tests. Jeder Tests bereitet seine Daten vor und räumt sie danach wieder auf.
- Klare Fehlermeldungen bei Assertions.
- Testklassen im selben Package wie Klassen.
- Coding Conventions einhalten.
JUnit Bad Practices
5 Punkte
- Test testet nicht gewünschtes Verhalten.
- Test testet mehrere Zustände gleichzeitig.
- Testdaten zufällig oder hardcoded im Test.
- Überprüfung der Vorbedingungen (weil unnötig).
- Logik in Tests.
Test Driven Development (TDD)
3 Phasen
- Red: Implementierung und Ausführung der Testfälle. Tests müssen Fehlschlagen.
- Green: Implementierung der Funktionalität. Testfälle erfolgreich.
- Refactor: Optimierung der Implementierung. Keine Änderungen am Verhalten, tests sollten weiterhin erfolgreich sein.
Test Doubles
Was sind sie, warum verwenden wir sie und was für Typen gibt es?
Austausch einer Komponente für eine simplifizierte Implementierung für Testzwecke.
+ Isolation
+ Effizienz
+ Flexibilität
Typen: Dummy Objekt, Fake Object, Spy, Stub, Mock
Testdoubles
Dummy Objekt
Leerer Platzhalter ohne funktionalität.
Wird in die Komponente gereicht, aber nicht zur Verwendung intentioniert.
Bsp. new DummyCustomer()
<- DummyCustomer eine eigene Klasse dafür.
Testdoubles
Fake Objekt
Ausführbare Implementierung, dient aber nicht zur Steuerung/Überprüfung des Testobjekts.
Verwendet wenn reale Implementierung zu langsam oder in Testumgebung nicht verfügbar (bsp. Datenbank).
Testdoubles
Spy
Kein Ersetzen sondern Erweiterung einer Komponente um Überwachungsfunktionen.
Zwischen Testobjekt und abhängiger Komponente.
Überwacht aufrufe und leitet sie aber weiter.
Testdoubles
Stub
Ausführbare Implementierung.
Liefert vordefinierte Werte.
Ermöglicht indirekt Steuerung der zu testenden Komponenten.
Testdoubles
Mock
Ausführbare Implementierung.
Liefert vordefinierte Werte.
Im gegensatz zu Stubs sind Mocks aber selbst Teil des Tests- überwacht Interaktionen, übergebene Parameter und überprüft Erwartungen an das Testobjekt.
Erkennt wenn unerwartete Werte eingehen.
Mocking Frameworks
Mockito
Mocks können mithilfe von Mocking Frameworks implementiert werden.
when(T methodCall).thenReturn(T value); when(T methodCall).thenThrow(Throwable t);
Mockito Argument Matcher zur Überprüfung der eingehenden Parameter.
Überprüfung der Aufrufe des Mocks mit Mockito.verify()
Definition Continuous Integration (CI)
Entwicklungsansatz, bei dem Code Änderungen laufend integriert, getestet und gebaut werden.
Jede Integration wird duch einen automatisierten Buildprozess begleitet.
Standard in agilen Projekten.
Grundprinzipien von CI
3
Häufige commits (“Commit daily - commit often”)
Häufige builds (“Build early - build often”)
Stabile builds (“Keep it green”)
Vorteile von CI
4 Punkte
- Schnelles und häufiges Feedback
- Frühzeitige Identifikation von Fehlern
- Vermeidung einer späten „Integrationshölle“
und „works on my maschine“ Problematik - Reduktion manueller Tätigkeiten
CI/CDE/CD
Continuous Integration (build, test, check)
Refactoring
Was ist es und was zählt als Refactoring? Motivation?
Systematischer Ansatz zur Verbesserung der Code Qualität.
Keine Änderungen des sichtlichen Verhaltens.
Nur Verbesserungen an der Struktur des Codes (z.B. keine Performanceverbesserungen).
Motivation: Verbesserter Design, Erhöhung der Verständlichkeit, Auffinden von Fehlern.
Technische Schuld
Schlechte Code Qualität = sich in Technische Schuld begeben.
Schulden müssen zurück gezahlt werden (durch Refactoring).
Anhäufung von schlechtem Code führt zu Verlust an Produktivität & Wartbarkeit, mehr Fehlern und höhere Fehlerkosten.
Refaktoring Vorgehensweise
3 Schritte
- Identifikation
- Testabdeckung
- Ausführung
Bad Smells
5 wichtige Gruppen
Bloaters (Code der über die Zeit gewachsen ist)
Object-Orientation Abusers
Couplers (Zu viel Abhängigkeit zwischen Klassen)
Change Preventers (Änderungen haben Auswirkungen auf viele andere Stellen)
Dispensables (Überflüssiger Code)