Start / Seminare / GitHub Actions in der Praxis
Modul
Tests und Qualitätsprüfungen automatisieren
4 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Tests und Qualitätsprüfungen automatisieren
0:00 Eine Prüfung, die man übergehen kann, ist keine Prüfung — sie ist eine Empfehlung mit rotem Symbol. Dieses Modul handelt davon, aus Prüfungen echte Tore zu machen. Wir sehen uns zuerst an, wie Integrationstests in einer Pipeline an ihre Datenbank kommen, und da gibt es zwei recht unterschiedliche Wege. Dann geht es um messbare Qualität: Linting, Typprüfung, Coverage — und um die Frage, wann eine Messung tatsächlich etwas bewirkt.
0:25 Und zum Schluss um den Mechanismus, der aus einer grünen Anzeige eine Bedingung macht: erforderliche Statusprüfungen, hinterlegt in den Regeln des Branches.
Tests und Qualitätsprüfungen automatisieren
0:35 Zweites Modul des zweiten Tages. Wir arbeiten uns von der Ausführung über die Messung zur Durchsetzung vor. Am Ende blockiert ein roter Pull Request der Beetkarte den Merge tatsächlich — und das ist der Unterschied zwischen einer Pipeline, die informiert, und einer, die schützt.
Tests in der Pipeline ausführen
0:52 Unit-Tests sind der einfache Teil — sie brauchen nichts als Code. Interessant wird es bei Integrationstests, denn die brauchen eine echte Datenbank. Und die muss irgendwo herkommen. Es gibt zwei Wege, und die Entscheidung dazwischen hat Folgen. Der eine sind Service Container: Sie beschreiben in der Workflow-Datei, welche Dienste GitHub neben dem Job starten soll.
1:14 Der andere ist Testcontainers — dann fährt der Test selbst seine Abhängigkeiten hoch, über die Docker-Schnittstelle des Runners. Der Unterschied ist weniger technisch als organisatorisch: Im ersten Fall steht die Datenbankversion in der Pipeline, im zweiten im Testcode. Und damit ist auch entschieden, ob Ihre Tests lokal genauso laufen wie in der Pipeline oder eben nicht.
1:36 Ein Dienst, ein Passwort, ein Port — und dann der Teil, den man beim ersten Mal vergisst: der Bereitschaftstest. Ohne ihn startet Ihr Test möglicherweise, während die Datenbank noch hochfährt, und scheitert an einer abgelehnten Verbindung. Das Fiese daran: Es passiert nicht immer, sondern abhängig von der Tagesform der Maschine. Genau solche Fehler bringen ein Team dazu, rote Läufe für Rauschen zu halten.
1:59 Nehmen Sie den Bereitschaftstest also von Anfang an mit — er kostet drei Zeilen und erspart Ihnen die Sorte Fehler, die man am schwersten reproduziert. Die Tabelle stellt die beiden Ansätze gegenüber, und die zweite Zeile ist die wichtigste: Lokal gleich oder nicht. Mit Service Containern haben Sie zwei Wahrheiten — eine in der Workflow-Datei, eine auf den Entwicklerrechnern —, und die driften auseinander.
2:23 Mit Testcontainers gehören Test und Umgebung zusammen, und die Pipeline muss nur Docker bereitstellen. Dafür bezahlen Sie mit etwas Startzeit je Testlauf. Für die Beetkarte nehmen wir Testcontainers, weil dieselbe Datenbankversion lokal und in der Pipeline mehr wert ist als ein paar gesparte Sekunden. Der erste und der dritte Punkt gehören zusammen und erklären die meisten sporadisch scheiternden Testsuiten: geteilte Daten und fehlendes Aufräumen.
2:49 Solange die Tests immer in derselben Reihenfolge laufen, fällt es nicht auf — bis jemand einen Test hinzufügt oder die Ausführung parallelisiert. Der zweite Punkt ist der Bereitschaftstest von eben. Und der vierte ist der stille Klassiker: In der Pipeline läuft eine andere Datenbankversion als in Produktion, und ein Verhalten, das dort abweicht, fällt hier nie auf.
Qualität messbar machen
3:09 Tests sind nur ein Teil der Prüfung. Jetzt geht es um alles, was sonst noch über Qualität aussagt — und um die Frage, wann eine Messung mehr ist als ein Bericht. Der entscheidende Satz lautet: Eine Prüfung wirkt nur, wenn sie den Lauf beenden kann. Linter, Typprüfung und Coverage-Schwellen liefern alle einen Rückgabewert, und den muss die Pipeline auch ernst nehmen. Sonst entstehen Berichte, die niemand liest.
3:33 Code Scanning ist ein Sonderfall: Es sucht nach Sicherheitsmustern und meldet in die Sicherheitsansicht statt in den Build. Das ist bewusst so — es soll Sie informieren, nicht jeden Pull Request blockieren. Diese Unterscheidung zwischen blockierend und informierend sollten Sie für jede Prüfung bewusst treffen. Die Reihenfolge folgt einer einfachen Regel: schnell vor langsam.
3:55 Formatierung, Linting und Typprüfung melden in unter einer Minute — wenn dort etwas kaputt ist, brauchen die Integrationstests gar nicht erst zu starten. Danach die Unit-Tests, zuletzt die Integrationstests mit ihrer Datenbank. Wichtig ist aber, dass daraus keine Kette wird: Parallele Jobs liefern alle Ergebnisse gleichzeitig, und dann sehen Sie im Pull Request auf einen Blick, was alles zu tun ist, statt nach jeder Korrektur den nächsten Fehler zu entdecken.
4:22 Der rote Faden dieser vier Schritte ist Realismus. Messen Sie zuerst den Ist-Wert und setzen Sie die Schwelle knapp darunter — nicht auf einen Wunschwert, den das Projekt heute nicht erreicht. Eine Schwelle, an der jeder Pull Request scheitert, wird nämlich nicht erfüllt, sondern abgeschaltet, und dann haben Sie gar nichts.
4:40 Die Prüfung muss abbrechen können, sonst ist sie wieder nur ein Bericht. Und dann heben Sie den Wert schrittweise an, wenn Tests hinzukommen. So wird aus der Kennzahl eine Sperrklinke, die den erreichten Stand hält. Der erste Punkt ist der Klassiker aller Linter-Einführungen: Ein Flag macht Fehler zu Warnungen, damit der Lauf endlich grün wird — und ab da meldet der Linter ins Leere.
5:02 Der zweite und der dritte sind Varianten davon: gemessen, aber nicht ausgewertet; eingerichtet, aber mit einem Schalter entschärft, der dann dauerhaft bleibt. Und der vierte ist ein statistisches Problem: Eine projektweite Schwelle lässt neue, ungetestete Module hinter einem guten Durchschnitt verschwinden. Wer das vermeiden will, misst die Änderung, nicht das Gesamtprojekt.
Ergebnisse sichtbar machen und erzwingen
5:24 Und jetzt der Schritt, der aus einer Prüfung ein Tor macht. Bis hierhin haben wir gemessen — nun sorgen wir dafür, dass die Messung eine Änderung tatsächlich aufhalten kann. Eine erforderliche Statusprüfung ist eine Prüfung, die in einem Ruleset oder im Branch-Schutz als Voraussetzung für den Merge hinterlegt ist. Erst wenn sie Erfolg gemeldet hat, lässt sich der Pull Request zusammenführen.
5:47 Das ist eine Einstellung am Repository, nicht in der Workflow-Datei — ein Punkt, der oft übersehen wird. Sie können also die beste Pipeline der Welt haben; solange niemand ihre Ergebnisse als Bedingung hinterlegt, sind sie eine Empfehlung. Annotationen ergänzen das, indem sie den Fehler direkt an der betroffenen Zeile anzeigen.
6:06 Diese Kette zeigt, wo die Prüfung im Ablauf sitzt: vor dem Review, nicht danach. Das ist mehr als eine Reihenfolge — es ist eine Frage des Respekts vor der Zeit der Kolleginnen und Kollegen. Niemand sollte Code lesen, den die Maschine noch nicht durchgewinkt hat. Formatierung, offensichtliche Fehler und fehlende Tests klärt die Pipeline; der Mensch kümmert sich um Entwurf und Verständlichkeit.
6:28 Und der dritte Kasten ist der, den wir gerade einrichten: Ohne grüne Prüfungen kommt der Pull Request an dieser Stelle nicht vorbei. Jetzt ein Detail mit unangenehmen Folgen: Erforderliche Prüfungen werden über den Jobnamen referenziert. Damit wird ein Name, den Sie bisher frei vergeben haben, zu einer Schnittstelle. Benennen Sie den Job um, zeigt die Bedingung ins Leere und jeder Pull Request hängt — mit einer Prüfung, die ewig aussteht.
6:54 Bei einer Matrix kommt erschwerend hinzu, dass die Namen die Kombinationswerte enthalten. Und der dritte Punkt schließt den Kreis zu Modul drei: Ein durch Pfadfilter ausgelassener Lauf meldet nichts, und ausstehend ist eben nicht grün. Die ersten beiden sind die Enden desselben Spektrums: Einmal blockiert eine falsch referenzierte Prüfung alles, einmal blockiert gar nichts, weil niemand die Prüfungen hinterlegt hat.
7:18 Der dritte betrifft Beiträge aus Forks, bei denen der Auslöser nicht greift — dann fehlen Prüfungen ausgerechnet dort, wo Sie den Code am wenigsten kennen. Und der vierte ist ein kulturelles Problem: Wenn Administratoren die Regeln umgehen dürfen, wird aus der Ausnahme die Gewohnheit, und die Regel gilt am Ende nur für die, die keine Rechte haben.
Übung
7:38 In der Übung wird aus den Prüfungen der Beetkarte ein Tor. Und wir prüfen das mit dem einzigen Nachweis, der zählt: einem Pull Request, der sich nicht zusammenführen lässt. Drei Prüfungen, ein Nachweis. Die Integrationstests laufen gegen eine echte PostgreSQL-Instanz, Linting und Coverage kommen dazu, und alle drei werden im Ruleset hinterlegt.
7:58 Der Nachweis ist der interessante Teil: Öffnen Sie einen Pull Request mit einem absichtlich fehlschlagenden Test und versuchen Sie, ihn zusammenzuführen. Wenn der Knopf sich klicken lässt, ist die Aufgabe nicht erfüllt — unabhängig davon, wie gut die Pipeline aussieht. Und denken Sie daran, den absichtlichen Fehler danach wieder zu entfernen.
8:18 Die Reihenfolge ist bewusst so gewählt. Erst die Integrationstests, weil sie die meiste Arbeit machen. Dann die schnellen Prüfungen als eigener Job — die laufen parallel und melden zuerst. Dann die Coverage-Schwelle, knapp unter dem Ist-Wert. Erst im vierten Schritt tragen Sie die Prüfungen als Bedingung ein, denn dann stehen die Jobnamen fest; andernfalls dürfen Sie es zweimal machen.
8:41 Und der fünfte Schritt ist der Beweis. Verlassen Sie sich nicht darauf, dass die Einstellung wirkt, nur weil sie gespeichert wurde. Der erste Punkt ist der Datenbankklassiker aus dem ersten Kapitel — er kommt in dieser Übung mit hoher Wahrscheinlichkeit vor. Der zweite und dritte sind die Fehler, die wir eben besprochen haben.
9:00 Und der vierte ist der, den man wirklich oft sieht: Der absichtlich fehlerhafte Test bleibt nach der Übung liegen, weil er ja rot ist und niemand ihn anfasst. Machen Sie es sich zur Regel, solche Nachweise sofort zurückzubauen. Im nächsten Modul verpacken wir die geprüfte Anwendung dann in ein Container-Image.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →