Kapitelklicken springt direkt hin
Shownotes
<p>Nach der Episode über die Fehler, spechen wir heute darüber, wie man sie vermeidet. Wie nicht anders zu erwarten, ist auch dies ein Thema, bei dem reichhaltige Meinungsdiskurse geführt werden.</p><h2>Shownotes</h2><img src="dl.xyrillian.de/noises/stp-038-intro.png" alt="Bild"></p>
<ul>
<li>
<p>Warum testen? -> siehe STP037</p>
</li>
<li>
<p>Anforderungen an Tests</p>
<ul>
<li>reproduzierbar: nicht abhängig von unerwarteten äußeren Einflüssen oder menschlicher Intervention</li>
<li>fokussiert: im Fehlerfall soll möglichst klar sein, wo das Problem liegt</li>
<li>schnell: damit man beim Ändern des Systems schnelles Feedback bekommt (siehe auch <a href="xkcd.com/303/">XKCD 303</a>)</li>
<li>realitätsnah: überprüft eine Funktion, die der Benutzer so tatsächlich benötigt</li>
</ul>
</li>
<li>
<p>manuelle Tests</p>
<ul>
<li>kostenintensiv: <a href="destructoid.com/apex-legends-qa-baton-rouge-la… braucht(e) 200 Tester</a> (das Spiel erlaubt Matches mit bis zu 60 Teilnehmern)</li>
<li>erfüllt von den obigen Anforderungen nur die Realitätsnähe</li>
<li>wenn's geht, lieber automatisieren</li>
<li>gängige Strategie: manuelle Tests zur Fehlersuche, im Zweifelsfall durch die Kunden ;) – dann Nachstellung des gefundenen Problems</li>
</ul>
</li>
<li>
<p>automatisierte Tests am Beispiel der <a href="commons.wikimedia.org/w/index.php?title=File:T…;
<ul>
<li><strong>Unit Tests</strong>: Überprüfung einer einzelnen Komponente in Isolation
<ul>
<li>besonders wertvoll, wenn die Komponenten auf besonders reproduzierbare Weise arbeiten (zum Beispiel pure Berechnungen; Vorgänge, die <em>nicht</em> Netzwerkzugriff/Festplattenzugriff/etc. erfolgen)</li>
<li>Problem: es reicht nicht, wenn jede Komponente für sich genommen funktioniert, aber sie nicht zusammen passen</li>
<li>Bewertung: reproduzierbar, fokussiert, schnell, aber nicht realitätsnah</li>
</ul>
</li>
<li><strong>Integration Tests</strong>: Überprüfung des Zusammenspiels mehrerer Komponenten eines Gesamtsystems
<ul>
<li>nach Möglichkeit Eingrenzung äußerer Faktoren, z.B. statt Kommunikation mehrerer Komponenten über ein reales Netzwerk Simulation einer Netzwerkstruktur im Programm oder mittels Containern/VMs (siehe STP023)</li>
<li>Bewertung: tendenziell weniger reproduzierbar, etwas langsamer, weniger fokussiert, aber realitätsnäher</li>
</ul>
</li>
<li><strong>End-to-End-Tests</strong> (E2E): Überprüfung des Verhaltens eines Gesamtsystems
<ul>
<li>analog zu den manuellen Tests, aber nach festem Algorithmus</li>
<li>höchster Aufwand in der Umsetzung, siehe insbesondere UI-Tests mittels <a href="en.wikipedia.org/w/index.php?title=Headless_br… Browser</a> etc.</li>
<li>Bewertung: am wenigsten reproduzierbar (aufgrund der Vielzahl an Variablen), am unfokussiertesten, am langsamsten, aber am nächsten an der Realität</li>
</ul>
</li>
<li>allgemeine Empfehlung: ganz viele kleine Unit Tests und einige mittelgroße Integrationstests für die schnelle Feedbackschleife, dazu einige wenige große E2E-Tests für den Abgleich mit der Realität</li>
</ul>
</li>
<li>
<p>alternative Teilung: <a href="de.wikipedia.org/w/index.php?title=Black-Box-T… vs. Whitebox-Tests</a></p>
<ul>
<li>Blackbox: Umsetzung eines Tests ohne innere Kenntnis der Struktur des Systems, z.B. anhand einer Spezifikation</li>
<li>Vorteil: ein Blackbox-Test durch ein anderes Team kann Missverständnisse des ursprünglichen Teams aufdecken</li>
<li>Nachteil: kann nur E2E sein</li>
</ul>
</li>
<li>
<p>die reine Lehre: <strong>Test Driven Development</strong> (<a href="de.wikipedia.org/w/index.php?title=Testgetrieb… Entwicklung</a>)</p>
<ul>
<li>neue Funktionalität darf man nur bauen, wenn es Testabdeckung dafür gibt</li>
<li>erst fehlschlagenden Test schreiben; dann Funktionalität einbauen, sodass der Test erfolgreich durchläuft; dann aufräumen</li>
<li>Xyrill macht lieber "Data Driven Development" und hat Bedenken</li>
</ul>
</li>
<li>
<p>Kann man die Qualität eines Tests bewerten? -> Idee: <a href="en.wikipedia.org/w/index.php?title=Code_covera… Coverage</a></p>
<ul>
<li>Welcher Anteil des Programmcodes wird von meinem Test tatsächlich abgedeckt?</li>
<li>Was heißt eigentlich "Anteil"?
<ul>
<li>Beispiel: <code>if (a or b or c) { return "Kredit abgelehnt" }</code> (einfach bei Zeilenabdeckung, schwierig bei Bedingungsabdeckung)</li>
<li>Beispiel: "Kommt ein Software-Tester in eine Bar."</li>
</ul>
</li>
<li>Problem: <a href="de.wikipedia.org/w/index.php?title=Goodharts_G… Gesetz</a>, "Sobald eine Metrik zu einem Ziel wird, hört sie auf, eine gute Metrik zu sein."</li>
<li>Problem: für manche Zeilen sind Tests wichtiger als andere (wichtig für vertrackte Logik, weniger wichtig für Sofortabbruch bei unerwarteten Fehlern)</li>
</ul>
</li>
<li>
<p>Tests muss man trotzdem noch schreiben. Kann man das wegautomatisieren?</p>
<ul>
<li><a href="de.wikipedia.org/w/index.php?title=Statische_C… Analyse</a>: automatische Suche nach bedenklichen Mustern (z.B. Datei wurde zum Schreiben geöffnet, wird aber am Ende nicht geschlossen -> Risiko des Datenverlusts; z.B. Verwendung veralteter kryptografischer Primitiven)</li>
<li><a href="de.wikipedia.org/w/index.php?title=Fuzzing&…;: anstatt eines Tests mit festen Werten ("bei Eingabe X wird Ausgabe Y erwartet") nur Vorgabe einer Struktur ("wenn hier ein Text reingesteckt wird, kommt da eine Zahl raus"), dann automatische Suche nach Absturzbedingungen</li>
</ul>
</li>
<li>
<p>Machen Tests die Sache immer besser?</p>
<ul>
<li><a href="de.wikipedia.org/w/index.php?title=Heisenbug&a…;: "ein Softwarefehler, der zu verschwinden oder sein Verhalten zu verändern scheint, wenn man versucht, ihn zu untersuchen"</li>
</ul>
</li>
<li>
<p>im Gespräch erwähnt:</p>
<ul>
<li><a href="de.wikipedia.org/wiki/ISO_9001">ISO900…;
<li><a href="forschergeist.de/podcast/fg034-werner-heisenbe… zu Werner Heisenberg</a></li>
</ul>
</li>
</ul>