Zum Inhalt springen

Suchen...

Dunkle Seite des Testens: Fehler, die wir selbst auslösen

Die dunkle Seite des Testens beginnt beim Aufbau: Ein Test kann den Ausfall auslösen, den er verhindern soll. Davor steht eine eigene Risikobewertung.

• • 9 Min. Lesezeit
Cover zum Expertengespräch über 'Dunkle Seite des Testens: Fehler, die wir selbst auslösen' mit Bart Knaack und Richard Seidl.

Die dunkle Seite des Testens bezeichnet die Fehler, die das Testen selbst verursacht: Testdaten, die aus einer schwach geschützten Testumgebung abfließen, Angreifer, die dort den Code studieren, oder ein fehlschlagender Test, der die Produktion lahmlegt. Jeder Testaufbau braucht deshalb vorab eine eigene Risikobewertung, am besten zusammen mit jemandem aus dem Netzwerk-Team.

Das Wichtigste in Kürze

  • Die dunkle Seite des Testens beginnt, wenn ein Test genau die Störung auslöst, die er verhindern sollte; wer die Folgen eines Tests nicht tragen kann, testet ihn nicht.
  • Nicht anonymisierte Produktionsdaten auf einer CD unterliegen keiner Governance, deshalb zerbrach Bart Knaack den Datenträger, statt die Daten zu anonymisieren.
  • Eine Testumgebung, die schwächer geschützt ist als die Produktion, lässt Angreifer in Ruhe den Code studieren und dessen Schwachstellen später gegen das Livesystem nutzen.
  • Testen in Produktion braucht eine eigene Risikobewertung, am besten mit einem Netzwerk-Engineer im Raum, der weiß, welche Umgebungen miteinander verbunden sind.
  • Aus 10.000 End-to-End-Testfällen wurden 50, nachdem das Team Prüfungen wie die Adressvalidierung in den Unit-Test verlagert hatte.

Die dunkle Seite des Testens beginnt vor dem ersten Testlauf

Wir testen, damit in der Produktion nichts schiefgeht. Dafür gibt es den Job. Die dunkle Seite des Testens ist, dass das Testen selbst Ausfälle verursachen kann: Testdaten, die nach außen gelangen, Testumgebungen, die Fremden einen Blick auf den Code geben, Produktionssysteme, die wegen eines fehlgeschlagenen Tests stehen. Bart Knaack sammelt solche Fälle aus seinen eigenen Projekten, und seine Diagnose ist knapp. Die meisten passieren, weil vorher niemand gründlich genug nachgedacht hat.

Seine Regel für den Moment vor dem Startknopf ist kurz.

„Wenn du die Konsequenz deines Tests nicht tragen kannst, dann teste es nicht.“

(Bart Knaack)

Die Fragen, die daraus folgen, haben eine Reihenfolge. Sollten wir das überhaupt bauen? Wie wollen wir es testen? Wie soll die Umgebung aussehen, und woher kommen die Daten? Lässt sich eine Umgebung aufbauen, die für das Vorhaben taugt, einen Performancetest zum Beispiel? Und wenn es keine eigene, produktionsnahe Umgebung gibt: Testen wir dann wirklich in der Produktion? Jede Antwort hat eine Konsequenz, und aus diesen Konsequenzen besteht die dunkle Seite.

Die meisten von Barts Beispielen liegen auf der nicht-funktionalen Seite, also bei IT-Sicherheit, Performance und Governance. Seine Erklärung dafür: Über funktionales Testen denken Teams meist gründlich nach. Die nicht-funktionalen Themen laufen nebenher, und von dort kommen die Überraschungen.

Wie gelangen Testdaten aus einer Testumgebung nach außen?

Testdaten fließen ab, wenn echte, nicht anonymisierte Daten auf einem System liegen, das schwächer geschützt ist als die Produktion. Eine Testumgebung bekommt selten denselben Schutz wie das Produktionssystem, das sie nachbildet. Wer hineinkommt, bekommt die Daten gleich mit.

Barts eigenes Beispiel brauchte nicht einmal einen Angreifer. Ein Kollege kam in sein Büro und bat ihn, ein paar Daten zu anonymisieren. Bart sagte zu und bat ihn, die Daten in eine sichere Umgebung zu legen. Der Kollege hatte sie auf einer CD dabei. Bart nahm die CD und zerbrach sie. Der Protest kam prompt, das seien seine Testdaten. Barts Antwort: Das sind Produktionsdaten auf einer CD, die keiner Governance unterliegen, und das machen wir nicht.

Die Lehre hängt weniger an der CD als am Prozess. Wie setzt du deine Tests so auf, dass sie sicher sind, und wer darf was wohin tragen? Das klärt man, bevor die Daten unterwegs sind.

Was sieht ein Angreifer in deiner Testumgebung?

Eine Testumgebung öffnet eine zweite Tür. Wer hineinkommt, kann dort in Ruhe studieren, wie der Code funktioniert, und jede Schwachstelle, die er findet, gegen die Produktion einsetzen. Die Umgebung ist „nur“ Test, entsprechend ist sie geschützt, und genau das macht sie für Angreifer brauchbar.

Dafür braucht auch ein Tester einen gewissen Einblick in die Infrastruktur seines Systems. Wer sie kennt, erkennt Schwachstellen und weiß, was er in der Testumgebung tun will und was besser nicht. Bart rät, den Schutz der Testumgebung als eigene Entwurfsfrage zu behandeln. Dasselbe gilt für eine separate Performance-Umgebung: Ist sie wirklich unabhängig von der Produktion, oder teilt sie sich eine Datenbank, ein Netzsegment, einen Service? Die Frage stellt man, bevor die Last anrollt.

Der Risikoprozess braucht seine eigene Risikobewertung

Bart ist kein Befürworter von Tests in der Produktion. Er weiß auch, dass es manchmal keine Wahl gibt. Dann gilt als Erstes: Du musst wissen, was du dort tust, denn du greifst in das Produktionssystem ein. Als Zweites musst du die Auswirkung eines fehlschlagenden Tests kennen. Wenn ein fehlschlagender Test die Produktion lahmlegen kann, wann genau willst du ihn dann laufen lassen?

Daraus wird eine Risikobewertung des Risikoprozesses selbst. Vielen Testern fällt schon das Nachdenken über gewöhnliche Produktrisiken schwer, und über die Risiken des eigenen Testens erst recht. Bart hält das trotzdem für den Job. Was ihn wundert, ist, wie oft Leute mit Tester-Mindset genau die Fehler machen, die sie anderen vorwerfen.

Sein praktischer Schritt ist einfach. Wann immer er so etwas aufsetzt, holt er einen Netzwerk-Engineer in die Session. Der weiß, mit welcher Umgebung die Testumgebung verbunden ist, wie sie aufgebaut ist und warum gerade diese Datenbank im Einsatz ist. Jemand aus dem Ops- oder Netzwerkteam sitzt mit den Testern am Tisch, und die Frage auf dem Tisch lautet: Was soll da schon schiefgehen? Danach kommt die zweite Hälfte des Testens in der Produktion, das Aufräumen.

Warum helfen Checklisten nur zur Hälfte?

Checklisten helfen beim Erinnern. Bart hat selbst einige geschrieben. Das Problem ist, dass eine Checkliste auch vom Denken abhält. Sind alle Kästchen abgehakt, schließt das Team daraus, dass nichts mehr schiefgehen kann, und in diesem Moment hört es auf, selbst zu denken. Sicher ist man in Barts Augen nie.

Deshalb hält er sich von Checklisten fern, so weit es geht, und arbeitet stattdessen mit Orientierung, also mit Vorschlägen und vor allem mit Fragen. Worüber solltest du nachdenken? Was willst du nachweisen, und wo? Solche Fragen lassen sich nicht abhaken, man muss sie beantworten.

Wie die Fragen gestellt werden, hängt vom Umfang ab. Bei einer großen End-to-End-Kette kann eine Gruppensitzung sinnvoll sein, weil sich die Leute gegenseitig auf Ideen bringen und einwenden, dass etwas für das eine System gilt und für das andere nicht. Große Meetings mit Agenda sind allerdings ein Aufwand, deshalb geht Bart bei kleineren Themen eins zu eins vor, manchmal in der Kaffeeecke mit zehn Minuten von jemandes Zeit. Diese Sessions nimmt er auf, lässt sie transkribieren und nutzt das Transkript als ersten Entwurf des Reports. Das Ergebnis schickt er anschließend herum, damit jeder prüfen kann, ob seine Aussage stimmt, und ergänzt, was andere gesagt haben.

Wer sagt, das passiert nie, soll es unterschreiben

Manchmal ist das Risiko für den Tester klar, und sonst will es niemand sehen. Barts Beispiel stammt aus einer Firma mit zwei Systemen, die über eine direkte Leitung verbunden waren. Als Tester fand er heraus, dass es schiefgehen würde, sobald sich zwei Nachrichten überholen. Die Antwort des Engineers: Das ist eine direkte Verbindung, Nachrichten überholen sich da nie, das ist ein Netzwerkthema, mach dir keine Gedanken.

Bart bat um die Aussage in schriftlicher Form, mit Unterschrift, und hängte sie an den Fehler. Drei Monate später war der Netzwerkverkehr so gewachsen, dass das eine Kabel nicht mehr reichte, ein Netzwerk kam dazwischen, und Nachrichten konnten sich überholen. Als das Team fragte, warum er das nicht getestet habe, schob er den Bericht über den Tisch.

Sein Schluss daraus klingt nicht nach Triumph. In den meisten Fällen hören die Leute zu; ein Hinweis wie „ihr habt eine Verbindung zur Produktion, schaut euch das vielleicht an“ reicht meist. Wenn nicht, sorg dafür, dass die Warnung festgehalten ist und du zeigen kannst, dass du das Richtige getan hast.

Warum sind 10.000 End-to-End-Testfälle ein Warnsignal?

Eine sehr große End-to-End-Suite heißt meist, dass Prüfungen an der teuersten Stelle gelandet sind, an der sie laufen können. Ein Team erzählte Bart mit einigem Stolz, es habe 10.000 End-to-End-Testfälle gebaut. Seine Antwort: Dann macht ihr etwas falsch. Für diese Tests muss es Alternativen in früheren Phasen geben.

Ein Beispiel war die Adressprüfung. Ob eine Adresse gültig ist, wurde im End-to-End-Test geprüft, und Bart fragte, warum das nicht im Unit-Test passiert. Das Team hatte Sorge, ein Unit-Test zeige nicht, ob die Prüfung auch End-to-End funktioniert. Bart hielt dagegen, dass etwas, das auf Unit-Ebene funktioniert, auch End-to-End funktioniert. Das Team verlagerte die Prüfungen nach unten und landete bei 50 End-to-End-Testfällen statt 10.000.

Hinter der Zahl stecken die Fragen, die Bart immer wieder stellt. Warum machen wir diesen Test, und warum auf diese Weise? Gibt es wirklich keinen anderen Weg? Wenn nicht, welche Risiken müssen vorher weg? Und wenn doch, gibt es eine weniger riskante Alternative, die dasselbe nachweist? Was willst du nachweisen, wo kannst du es nachweisen, und musst du es an der Stelle tun, an der du es gerade tust? Dieselbe Logik legt er an Tests in der Produktion an.

Qualität ist eine gemeinsame Sache

An die Silos von Testern und Entwicklern glaubt Bart nicht mehr. Sein Rat für den Anfang: Setz dich als Tester mit deinem Entwickler zusammen und besprich genau diese Fragen. In gemeinsamen Workshops stellte er fest, dass Entwickler die Testtechniken oft nicht kennen, Grenzwertanalyse oder Äquivalenzklassenbildung etwa, mit denen sich gute Unit-Testfälle entwerfen lassen. Also halfen die Tester beim Aufbau dieser Fälle und beim Setzen richtiger Asserts. Manche Tests hatten unten nur ein „assert is true“. Sie erhöhten die Code Coverage und konnten nie fehlschlagen. Auf die Frage, was so ein Test beweist, lautete die ehrliche Antwort: nichts. Bart führte Mutation Testing ein, das den Wert solcher Tests deutlich besser zeigt als das, was er den Code-Coverage-Trugschluss nennt.

Niemand löst das an einem Tag. Langsam anfangen, Beispiele geben, die Leute erleben lassen, was diese Arbeitsweise bedeutet. Barts aktuelles Beispiel ist Contract-based Testing zwischen Consumer- und Producer-Seite zweier APIs. Vor 20 Jahren hat er das von Hand gemacht: Consumer-Protokoll nehmen, Producer-Protokoll nehmen, abgleichen, und die Abweichungen liegen offen, ein Integer auf der einen Seite, ein String auf der anderen. Die ersten Bugs fand er, bevor eine Zeile Code geschrieben war, und die Kollegen hielten das für eine besondere Fähigkeit. Er hatte zwei Dokumente gelesen und verglichen.

Das führt ihn zur Wurzel der meisten dieser Fehler. Die Leute reden nicht miteinander, und sie hören einander nicht zu. Sie bekommen eine Aufgabe, gehen ihren eigenen Weg, tun, was sie für nötig halten, und am Ende passt es nicht zusammen. Vieles davon ist Kommunikation, und die, so Bart, wird uns die KI nicht abnehmen.

Eine Frage lässt er für die nächste Runde offen. Wenn du eine KI testest, worüber musst du dir dann Gedanken machen? Das Testen von KIs hält Bart für die nächste Stufe, um die kein Team herumkommt. Er verweist auf eine BBC-Dokumentation, in der bösartig trainierte KIs ihre Absichten in der Testumgebung verborgen und erst in der Produktion gezeigt haben. Wenn das heute noch nicht passiert, sagt Bart, dann passiert es in Zukunft.

Diese Seite teilen

Ähnliche Beiträge