4 - Testen II: Test-Arten, Coding Conventions
Software Testen Grundlagen
ISTQB Testprinzipien
- Testen zeigt Fehler auf
beweist aber nicht Fehlerfreiheit
“Testen zeigt die Anwesenheit von Fehlern, nicht die Abwesenheit”
- Vollständiges Testen ist nicht möglich
Nicht alle Kombinationen an Eingaben, Vorbedingungen, Zuständen testbar (praktikabel zu testen)
Stattdessen priorisiert nach Risiko testen
- Frühzeitig Testen
Je früher Fehler gefunden werden desto einfacher und günstiger zu beheben
- Fehlerhäufungen beachten
Fehler sind nicht gleichmäßig verteilt - tendenziell dort wo Fehler gefunden auch mehr zu erwarten
- Veränderung statt Wiederholung
Wiederholtes ausführen von den selben Testcases wird keine neuen Fehler finden
- Testen ist kontextabhängig
- Trugschluss: Fehlerlose Systeme sind brauchbar
Fehler finden, beheben garantiert nicht, dass Produkt den Anforderungen und Bedürfnissen vom Benutzer entspricht
Potentielle Fehlerquellen
Fehler in Anforderungen / Spezifikationen
Fehler im Design
durch ungenauen, falsch interpretierten Anforderungen
durch Mangel an Erfahrung mit Technologie
Fehler in Testdaten
Teststufen
Teststufen sind Tests auf unterschiedlichen Ebenen des Entwicklugnsprozesses.
Eine Teststufe besteht aus einem oder mehreren Test-Typen (bestimmte Art von Tests).
Testtypen: Review, Funktionaler-Test, Massentest, Stresstest, Performancetest.
Akzeptanztests / Abnahmetests
Testen ob System im produktiven Einsatz den Abnahmekriterien vom Kunden entspricht (Validierung).
Dient nicht dazu Fehler im System zu finden.
wie Systemtest nur von Kunde, Benutzer ausgeführt
Stufen von Akzeptanzkriterien
Bedingung / Anforderung (Condition of Satisfaction)
Beispiel: beim Login Passwörter dürfen nicht knackbar sein Beispielhafte
Akzeptanzkriterien (Acceptance Criteria)
Definition für “nicht einfach knackbar” aus Condition of Satisfaction:
Min 8. Zeichen, nur alphanumerisch, mind. eine Zahl, ...
Systemtests
Testen vom integrierten System nach Kunden-Anforderungen (Validierung) und nach Spezifikation (Verifikation).
Basiert auf: Anforderungsspezifikation, Use-Cases, Geschäftsprozesse.
Testumgebung sollte Abbild der Produktivumgebung sein (keine umgebungsspezifischen Fehler).
von unabhängigem Testteam ausgeführt
Integrationtests
Testen mit dem Ziel Fehler in Interaktion zwischen Komponenten / Schnittstellen zu finden.
Zusammenführung (Integration) von mehreren Komponenten.
von Entwicklern erstellt und ausgeführt
Bottom-up, Top-Down, Big-Bang Strategien
Bottom up
Basis ausprogrammiert, dann Test-Treiber erstellt, dass Objekte erzeugt.
Nach jeder Integrationsstufe wird Treiber verändert und eine Ebene höher gestellt.
Top down
Zuerst die obersten Module entwickelt und darauf den der Test-Treiber aufsetzt.
Alle darunterliegenden Module werden mithilfe von Stubs simuliert.
Stubs werden je nach Integrationsstufe im echten Code befüllt.
Vorteil: Es gibt nur einen Testtreiber.
Kann mehrere Integrationsstufen haben
Komponententests / Modultests / Unittests
Testet Komponente isoliert vom restlichen System gegen Spezifikation.
braucht Zugang zu Source-Code
Testet Implementierung: Argumente werden übergeben, Ausgabe wird kontrolliert
von Entwicklern erstellt und ausgeführt
Privater Test
Vom Entwickler vor der Freigabe, undokumentiert
Regressionstests
Vor Durchführung von Veränderungen - Wiederholung von Tests
Testentwurfsverfahren
Blackbox Tests(Box geschlossen lassen)
basiert auf Spezifikation ohne Wissen über innere Struktur
Daten-getrieben (Input-Output getrieben)
Überdeckung von Anforderungen
Partitionierung der Eingabedaten
Whitebox Tests(in Box hineinschauen)
basiert auf Code-Struktur, Modulen mit Wissen über innere Struktur
Logik-getrieben
Überdeckung von Knoten, Kanten, Pfaden
Partitionierung von Eingabedaten für Bedingungsüberdeckung ( )
Erfahrungsbasiertes Testen / Exploratives Testen
zusätzlich zu anderen Testentwurfsverfahren
basiert auf Intuition, Erfahrung des Testers
zB Erfahrung aus anderen Projekten, Stellen die unter Zeitdruck entstanden sind etc.
muss dokumentiert werden
Unit Tests
JUnit
Unit Tests Grobstruktur
- Set-Up (Vorbereitung)
- Exercise (Ausführung)
- Verify (Auswertung)
- Tear-Down (Nachbearbeitung / zerstören)
Testframework für Unit Tests
Automatische Ausführung von Komponententests: xUnit
JUnit, CPPUnit, NUnit, ...
Benennung
Testmethoden einheitlich benannt
(Test)<UseCase/Method>_should<ExcpectedOutcome>
Beispiele
@Test public void testAdd_shouldContainAddedWord() {...}@Test public void testAdd_moreThanMax_shouldReplaceFirstWord() {...}@Test public void testRemove_Null_shouldThrowNullPointerException() {...}
Unit Testing - Best Practices
-
Testfälle sind isoliert
keine Abhängigkeiten zueinander: Jeder Testfall bereitet eigene Daten vor, räumt sie auf
- Keine Logik in Tests (Abfragen, Schleifen, try/catch)
-
Jeder Testfall testet nur einen Aspekt bzw Zustand
Nur ein Testfall per Methode
Keine Zufallsdaten sondern Äquivalenzklassen
- Namenskonventionen einhalten
- Verständliche Fehlermeldungen bei Assertions
- Klassen und Testklassen liegen im selben Package
TDD
Beispiel
Test Abdeckung: Kontrollflussorientierte Testverfahren
Tools zur Überprüfung der Testabdeckung: Clover, Cobertura, JaCoCo
Test Abdeckung
Code Coverage - sieht man in Coverage Reports
Kontrollflussorienterte Verfahren
= Überdeckungstests(für Code Coverage)
strukturorientiert (basiert auf Kontrollfluss des Programmes)
relevant auf Unit Test Ebene (Whitebox Tests)
definieren keine Regeln für Erzeugung von Testdaten
Test-Arten
Man kann auch coverage von Klassen und Funktionen testen.
- Anweisungsüberdeckung / Statement Coverage
Jede Anweisung min 1x durchlaufen
Zeigt ob toter Code existiert (falls sie nie durchlaufen werden können)
Zu schwaches Kriterium für sinnvolle Tests
- Zweigüberdeckung / Branch Coverage
Jede Kante min 1x durchlaufen
Zeigt ob nicht ausführbare Programmzweige existieren
- Bedingungsüberdeckung / Condition Coverage
Ziel: Überprüfung zusammengesetzter Entscheidungen und Teilentscheidungen
-
Einfacher Bedingungsüberdeckungstest
Alle atomaren Teilentscheidungen gleichzeitig true oder false
-
Mehrfach-Bedingungsüberdeckungstest
Test aller true/false-Kombinationen der atomaren Teilentscheidungen
Beispiel
Entscheidung:
(((a == 0) || (b < 5)) && (x < 6) || (y == 0)))
((A || B) && (C || D))
sind
a
,b
,x
,y
unabhängig können die TeilaussagenA
,B
,C
,D
unabhängig voneinander true oder false sein.Dadurch Kombinationen bzw Testfälle.
- Pfadüberdeckung / Path Coverage
Abdeckung aller möglichen Pfade (Knotenfolgen)
für komplexe Module nicht geeignet (vor allem wenn Schleifen involviert sind)
Sourcecode Qualitätskriterien
Toolgestützte Code Analysen für statische QS-Methoden.
Coding Conventions
Tools zur Überprüfung von Coding Standards: Checkstyle, IDE wie zB IntelliJ
Coding Conventions / Code Guidelines
Einheitlicher Stil im Projekt für jede Programmiersprache
bessere Lesbarkeit, Verständlichkeit
Eigene Regeln für
• Dokumentation • Einrückung (space/tab) • Max Zeilenlänge • Import Reihenfolge • Methoden/Feld Reihenfolg, Modifier/Sichtbarkeit, Veränderbarkeit • System.out Vermeidung, Logging • Namenskonventionen • Code Formatierung
Kontrolle
Commit conventions, Commit management
Commit messages
Gute Messages:
- Warum wurde diese Änderung gemacht? Was wurde geändert?
- nur eine logische Änderung pro Commit
- Idempotent (in sich geschlossen)
Zweck von Commit Messages:
- Beschleunigung des Review-Prozesses
- Unterstützen das Erstellen von Release Notes
- Erleichtern zukünftige Wartung
Commit Management
https://www.conventionalcommits.org
Vorteile: Changelogs, Tracability, bessere Maintainability