Verbessere deine Google-DevOps-Kenntnisse mit unseren Expertentipps und -einblicken. Erweitere dein Wissen und deine Expertise in Google DevOps.
Kontinuierliches Testen ist bei großen Projekten nicht unmöglich. Aber es ist eine Herausforderung. Die hier genannten fünf Punkte decken einen Großteil der möglichen Schwierigkeiten ab. Die Herausforderung sollte jedoch angenommen werden, da kontinuierliches Testen die Entwicklung von Software erheblich beeinflussen und die Angst vor Änderungen in einem bestehenden System verringern kann.
Die kontinuierliche Integration ist eine etablierte Praxis in Softwareprojekten, um die von verschiedenen Entwicklern vorgenommenen Änderungen am Quellcode kontinuierlich zusammenzuführen. Im Allgemeinen kann der Prozess in zwei Schritte unterteilt werden: den Kompilierungs- und den Testprozess. In diesem Artikel werden einige Herausforderungen hervorgehoben, die im Bereich des Testens bei großen Projekten auftreten können.
In modernen Projekten läuft ein Großteil der Tests vollautomatisch ab. Techniken wie die testgetriebene Entwicklung (TDD) haben sich als positiv für den Projektfortschritt, die Architektur und die Abdeckung erwiesen. Die Anzahl der für die Ausführung verfügbaren Tests steigt durch solche Methoden kontinuierlich an. Im Idealfall würden alle vorhandenen automatisierten Tests bei jeder Änderung des Quellcodes ausgeführt werden. Dadurch würde sichergestellt, dass bereits implementierte Funktionen durch neue Änderungen nicht beeinträchtigt werden. Allerdings werden in der Literatur zur kontinuierlichen Integration neue Herausforderungen nicht berücksichtigt. Zunächst können und sollten alle Tests bei jeder Änderung ausgeführt werden. Wir vernachlässigen jedoch den Faktor der Ausführungszeit für die Testsuite, die ständig zunimmt und bis zu mehreren Stunden betragen kann. Dies führt zu langen Feedbackschleifen, die wir zu vermeiden versuchen. Die folgenden fünf Faktoren können dazu führen, dass kontinuierliche Tests fehlschlagen.
Im Idealfall führt die Verteilung der Tests auf verschiedene Ebenen zu einer Pyramide, die von Modultests als Grundlage bis zu Integrationstests und Systemtests an der Spitze aufsteigt. Dies ist als Testpyramiden-Metapher von Mike Cohn bekannt.
Bei vielen Projekten finden wir jedoch eine umgekehrte Pyramide, den sogenannten Ice-Cone, bei dem die meisten Tests auf einem sehr hohen Niveau liegen. Im schlimmsten Fall sind alle Tests UI-basiert oder manuell. Diese Tests sollten den kleinsten Teil der Test-Suite ausmachen. Aber warum hat das negative Auswirkungen? Tests auf höheren Ebenen weisen einige oder alle der folgenden negativen Eigenschaften auf:
· Hohe Ausführungszeit
· Hoher Analyseaufwand im Fehlerfall
· Hoher Wartungsaufwand (insbesondere bei UI-Tests)
· Erhöhte Instabilität während der Testausführung
Andererseits ist es nicht sinnvoll, wenn eine Testsuite nur aus Komponententests besteht. Diese Tests prüfen sehr schnell, ob eine Änderung in einem lokalen Bereich die vorhandene Funktionalität beeinträchtigt hat, aber nicht, ob die einzelnen Teile der Software korrekt zusammenarbeiten. Daher ist es unerlässlich, die Anzahl der Tests auf den jeweiligen Ebenen in Form einer Pyramide darzustellen. Jede dieser Ebenen deckt einen separaten Aspekt ab, der getestet werden sollte, von der Funktionalität einzelner Klassen bis hin zur Funktionalität des gesamten Systems. Es wird auch getestet, ob das System die nicht-funktionalen Anforderungen erfüllt.
Unit-Tests werden idealerweise zusammen mit dem Produktcode kontinuierlich angepasst und verbessert. Daher ist die Alterung des Codes in der Regel kein Problem. Sobald man sich jedoch den System-Level-Tests nähert, wird man zunehmend das Phänomen beobachten, dass der Testcode nicht mehr berücksichtigt wird, sobald er in die Quellcodeverwaltung aufgenommen wurde. Dies kann im Laufe der Zeit, insbesondere auf den höheren Teststufen, zu Problemen führen. Testsuiten, die anfangs in wenigen Sekunden ausgeführt wurden, können nun Minuten bis Stunden dauern.
Außerdem können sich in den Tests technische Schulden ansammeln, wie z. B. doppelter Code oder fehlendes Refactoring. Dadurch wird die Wartung der Testsuite immer schwieriger. Du befindest dich dann in einer Situation, in der es zeitaufwendiger ist, die Tests anzupassen, als das Produkt zu implementieren. Deshalb muss die Qualität der automatisierten Tests kontinuierlich verbessert werden. Du kannst beispielsweise die fünf langsamsten Tests in jeder Iteration analysieren, um zu sehen, ob du sie beschleunigen kannst.
In jedem großen Projekt gibt es Tests, die ein nicht deterministisches Ergebnis liefern (Flaky Tests). Sie sollten nicht existieren, aber sie existieren! Der automatisch ausgelöste Build-Prozess in unseren Continuous-Integration-Praktiken ist daher sporadisch grün oder rot. Dies verringert das Vertrauen in unser Continuous-Integration-System.
Dieses Problem sollte nicht ignoriert werden. Wenn man sich die „Broken-Window-Theorie“ ansieht, die besagt, dass man anfängt, etwas zu vernachlässigen, sobald die ersten Mängel auftreten, beginnt man, die Continuous-Integration-Build-Ergebnisse zu ignorieren. Aussagen wie „Ich bin fertig, wenn 95 % meiner Tests grün sind“ oder „Diese fünf Tests schlagen sporadisch fehl, aber alles funktioniert“ sind das Ergebnis. Aber was ist, wenn es 94 % statt 95 % sind? Oder wenn sechs Tests statt fünf auf einmal fehlschlagen? Oder fünf völlig unterschiedliche Tests fehlschlagen und niemand es bemerkt, weil man sich nur auf die Anzahl der fehlgeschlagenen Tests konzentriert?
In einem System, das kontinuierlich automatisierte Tests durchführt, sollten instabile Tests daher separat mit einem separaten Prozess behandelt werden. Martin Fowler verwendete den Begriff „Quarantäne“. Im Prinzip geht es darum, dass ein Test, der sporadisch fehlschlägt, nicht in die normale Test-Suite aufgenommen werden sollte. Ähnlich wie bei einer hochansteckenden Krankheit, bei der die infizierten Personen unter Quarantäne gestellt werden müssen, sollten diese Tests aus der normalen Ausführung entfernt werden, um zu verhindern, dass die Ergebnisse des Builds ignoriert werden. Die Tests müssen natürlich untersucht werden und dann entweder das Produkt repariert oder der Test korrigiert werden. Wenn das Problem nicht innerhalb weniger Stunden gelöst werden kann, sollte dies außerhalb des normalen Build-Prozesses erfolgen, um zu vermeiden, dass es kein positives Ergebnis hat. Mit der Einführung der Testquarantäne sollte auch überwacht werden, wie viele Tests unter Quarantäne gestellt wurden, um zu vermeiden, dass plötzlich keine Tests mehr in der normalen Testausführung vorhanden sind.
Ein weiterer möglicher Fehler ist, dass die für Continuous Integration und Continuous Testing verwendeten Tools zu komplex sind. Sie sollten so einfach wie möglich zu bedienen sein, da sie mehrmals täglich von fast allen Entwicklern und Testern verwendet werden. Dies bedeutet jedoch auch, dass die Tools nicht getrennt für die Bereiche „Kompilieren“ und „Testen“ betrachtet werden können. Diese Aspekte müssen Hand in Hand gehen, um allen Beteiligten die tägliche Arbeit so einfach wie möglich zu machen. Es sollte klar definiert sein, was von einem Test in Bezug auf sein Verhalten erwartet werden kann und was die Aufgabe der Infrastruktur sein sollte. Auf diese Weise kann entschieden werden, welche Maßnahmen mit den Tools ergriffen werden sollen und was in der Verantwortung der Tests liegt. Typische Beispiele sind Konfigurationsänderungen, die ein Test vornimmt, um ausgeführt zu werden. Der Test ist dafür verantwortlich, sie zurückzusetzen (auch im Fehlerfall).
In vielen Projekten wird die Entwicklung von Testcode immer noch nicht als Softwareentwicklung betrachtet. Tatsächlich sind sie jedoch ein wichtiger Bestandteil des Produktcodes. Bei komplexen Projekten ist die Entwicklung von Testcode ebenfalls eine große Herausforderung und muss mit den gleichen Softwareentwicklungsmethoden wie die Produktentwicklung angegangen werden. Wenn die Qualität des Produktcodes schlecht ist, ist eine automatisierte Testsuite mit guter Qualität erforderlich. So kann die Qualität des Produktcodes schrittweise erhöht werden und man kann sich auf die Sicherheit hochwertiger Tests verlassen.
Wenn jedoch auch die Qualität des Testcodes nicht gut ist, kostet die Korrektur von Fehlern, die im Feld gefunden werden, viel Zeit. Das bedeutet, dass ein hoher Anteil der Kosten nach der eigentlichen Entwicklung, d. h. während der Wartungsphase, anfällt. Daher ist es wichtig, eine Architektur mit klaren Regeln für den Testcode aufzustellen und die Qualität des implementierten Codes zu messen. Im besten Fall wird die Architektur des Testcodes auf die gleiche Weise beschrieben wie die Architektur des Produktcodes, um sicherzustellen, dass alle Projektbeteiligten diese Dokumentation auf die gleiche Weise lesen können.
Kontinuierliches Testen ist bei großen Projekten nicht unmöglich. Aber es ist eine Herausforderung. Die oben genannten fünf Punkte decken einen Großteil der möglichen Schwierigkeiten ab. Die Herausforderung sollte jedoch angenommen werden, da kontinuierliches Testen die Entwicklung von Software erheblich beeinflussen und die Angst vor Änderungen in einem bestehenden System verringern kann. Eine Investition in die Zukunft.
Entdecke Einblicke, Trends und Ratschläge von Experten. Bleib informiert und inspiriert mit unseren neuesten Artikeln und Branchen-Updates.