Effektive Testautomatisierungsansätze für moderne CI/CD-Pipelines
InfoQ-Homepage-Artikel Effektive Testautomatisierungsansätze für moderne CI/CD-Pipelines
Dieser Artikel auf Japanisch
31. Mai 2023 20 Minuten Lesezeit
von
Craig Risi
rezensiert von
Matt Campbell
Der Aufstieg von CI/CD hatte massive Auswirkungen auf die Welt des Softwaretests. Da Entwickler von Pipelines verlangen, dass sie schnelles Feedback darüber geben, ob ihr Software-Update erfolgreich war oder nicht, sind viele Testteams gezwungen, ihre bestehenden Testautomatisierungsansätze zu überdenken und Wege zu finden, ihre Bereitstellung zu beschleunigen, ohne Kompromisse bei der Qualität einzugehen. Diese beiden Faktoren widersprechen sich in der Testwelt oft, da die Zeit oft der größte Feind bei der Suche eines Testers ist, so gründlich wie möglich die gewünschte Testabdeckung zu erreichen.
Wie gehen Teams also mit dieser bedeutenden Änderung um, um sicherzustellen, dass sie qualitativ hochwertige automatisierte Tests liefern und gleichzeitig die Erwartungen erfüllen können, dass die CI-Pipeline schnell Feedback zurückgibt? Nun, es gibt viele verschiedene Möglichkeiten, dies zu betrachten, aber es ist wichtig zu verstehen, dass die Lösungen weniger technischer und eher kultureller Natur sind – wobei der Testansatz geändert werden muss und keine großen technischen Verbesserungen an den Test-Frameworks vorgenommen werden müssen.
Am offensichtlichsten ist es vielleicht, nach links zu wechseln. Die Idee des „Shifting Left“ (wobei das Testen zu einem früheren Zeitpunkt im Entwicklungszyklus verschoben wird – vor allem auf Design- und Unit-Test-Ebene) ist in der Branche bereits weit verbreitet, wird von vielen Organisationen vorangetrieben und wird immer häufiger. Ein starker Fokus auf Unit-Tests ist eine gute Möglichkeit, Code schnell zu testen und schnelles Feedback zu geben. Schließlich werden Unit-Tests in einem Bruchteil der Zeit ausgeführt (da sie während der Kompilierung ausgeführt werden können und keine weitere Integration mit dem Rest des Systems erfordern) und können bei richtiger Durchführung eine gute Testabdeckung bieten.
Ich habe viele Tester davor zurückschrecken sehen, Unit-Tests durchzuführen, weil dabei Tests für eine sehr kleine Komponente des Codes geschrieben werden und die Gefahr besteht, dass wichtige Dinge übersehen werden. Dies ist oft nur eine Befürchtung aufgrund der mangelnden Transparenz im Prozess oder eines mangelnden Verständnisses von Unit-Tests und nicht eines Scheiterns der Unit-Tests selbst. Eine starke Basis an Unit-Tests funktioniert, da diese schnell ausgeführt werden können, während der Code in der CI-Pipeline erstellt wird. Es ist sinnvoll, so viele wie möglich zu haben und jede Art von Szenario abzudecken.
Das größte Problem besteht darin, dass viele Teams nicht immer wissen, wie sie es richtig machen. Erstens sollten Unit-Tests nicht als eine Aktivität mit Kontrollkästchen betrachtet werden, sondern vielmehr mit der richtigen Analyse und dem Engagement für das Testdesign angegangen werden, das Tester normalerweise anwenden würden. Und das bedeutet, dass Sie Unit-Tests nicht nur den Entwicklern überlassen, sondern Tester in den Prozess einbeziehen sollten. Auch wenn ein Tester nicht so gut im Codieren ist, kann er dennoch dabei helfen, herauszufinden, nach welchen Parametern beim Testen gesucht werden muss und an welchen Stellen er sie durchsetzen muss, um die richtigen Ergebnisse für die später zu testende integrierte Funktionalität zu liefern. Wenn Sie Ihre Testexperten von der Beteiligung am Unit-Test-Ansatz ausschließen, besteht die Möglichkeit, dass bei Unit-Tests einige wichtige Validierungsbereiche außer Acht gelassen werden. Dies ist oft der Grund, warum viele Tester Unit-Tests schlecht bewerten. Das liegt nicht daran, dass Unit-Tests wirkungslos wären, sondern einfach daran, dass sie oft nicht die richtigen Szenarien abdeckten.
Ein zweiter Vorteil der frühzeitigen Einbindung von Testern besteht darin, dass der Aufwand für Unit-Tests transparenter wird. Die Menge an Zeit (und damit Geld), die möglicherweise dadurch verschwendet wird, dass Teams ihre Testaufwände verdoppeln, weil die Tester am Ende einfach etwas testen, was bereits durch automatisierte Tests abgedeckt wurde, ist wahrscheinlich recht hoch. Das heißt nicht, dass keine unabhängige Validierung stattfinden sollte, aber sie sollte nicht übertrieben sein, wenn Szenarien bereits abgedeckt wurden. Stattdessen kann sich der Tester darauf konzentrieren, bessere explorative Tests bereitzustellen und seine eigenen Automatisierungsbemühungen auf Integrationstests für Grenzfälle zu konzentrieren, die er sonst möglicherweise nie abgedeckt hätte.
Um dies effektiv zu erreichen, ist jedoch ein erhebliches Maß an bewusstem Aufwand und Design erforderlich. Es geht nicht nur darum, sich mehr auf die Unit-Tests zu konzentrieren und vielleicht eine Person mit ausgeprägten Fähigkeiten in der Testanalyse hinzuzuziehen, um sicherzustellen, dass Testszenarien angemessen entwickelt werden. Außerdem müssen User Stories und Anforderungen spezifischer sein, um angemessene Tests zu ermöglichen. Oftmals können User Stories auf hoher Ebene enden und sich nur auf die Details der Benutzerebene und nicht auf der technischen Ebene konzentrieren. Es muss klar sein, wie sich einzelne Funktionen verhalten und mit ihren entsprechenden Abhängigkeiten interagieren sollen, damit gute Unit-Tests durchgeführt werden können.
Ein Großteil der Kritik, die Unit-Tests seitens der Test-Community entgegenbringen, ist die schlechte Integration, die sie bieten. Nur weil eine Funktion isoliert funktioniert, bedeutet das nicht, dass sie in Verbindung mit ihren Abhängigkeiten funktioniert. Dies ist oft der Grund, warum Tester so viele Fehler schon früh in ihren Testbemühungen entdecken. Dies muss nicht der Fall sein, da detailliertere Spezifikationen zu genauerem Mocking führen können, wodurch sich die Unit-Tests realistischer verhalten und bessere Ergebnisse liefern. Es wird immer „nachgeahmte“ Funktionen geben, die nicht genau bekannt sind oder nicht genau entworfen wurden, aber wenn man frühzeitig darüber nachdenkt, lässt sich dieser Nacharbeitsaufwand erheblich reduzieren.
Beim Design geht es jedoch nicht nur um Unit-Tests. Eines der größten Hindernisse für die direkte Ausführung der Testautomatisierung in der Pipeline besteht darin, dass das Team, das sich mit dem größeren integrierten System befasst, mit einem Großteil seiner Test- und Automatisierungsbemühungen erst beginnt, wenn der Code in einer größeren Umgebung bereitgestellt wurde. Dies verschwendet entscheidende Zeit im Entwicklungsprozess, da bestimmte Probleme erst später entdeckt werden und es genügend Details geben sollte, damit Tester zumindest mit dem Schreiben des Großteils ihrer automatisierten Tests beginnen können, während die Entwickler auf ihrer Seite programmieren.
Dies bedeutet nicht, dass keine manuelle Überprüfung, explorative Tests und die tatsächliche Verwendung der Software stattfinden sollten. Dies sind kritische Teile jedes Testprozesses und wichtige Schritte, um sicherzustellen, dass sich die Software wie gewünscht verhält. Diese Ansätze sind auch wirksam bei der Fehlersuche im vorgeschlagenen Entwurf. Durch die Automatisierung der Integrationstests kann der Prozess jedoch optimiert werden. Diese Tests können dann in die anfänglichen Pipelines einbezogen werden, wodurch die Gesamtqualität des gelieferten Produkts verbessert wird, indem dem Entwicklungsteam schneller Rückmeldung über Fehler gegeben wird, ohne dass das Testteam überhaupt eingreifen muss.
Ich habe viel über spezifische Designansätze und den Rest gesprochen, um die besten Testergebnisse zu erzielen. Sie können jedoch immer noch nicht alles, was Sie testen, automatisieren, da dies einfach nicht machbar ist und die Ausführungszeit der CI/CD-Pipelines zu sehr verlängert. Daher ist es von entscheidender Bedeutung zu wissen, welche Szenarien für Automatisierungszwecke angemessen Unit- oder Integrationstests unterzogen werden müssen, während gleichzeitig versucht wird, unnötige Duplikate des Testaufwands zu vermeiden.
Bevor ich mich mit diesen verschiedenen Tests befasse, möchte ich darauf hinweisen, dass das Ziel zwar darin besteht, Duplikate zu beseitigen, es aber wahrscheinlich immer ein gewisses Maß an Duplikaten geben wird, das über alle Tests hinweg erforderlich sein wird, um das richtige Maß an Abdeckung zu erreichen. Sie möchten versuchen, es so weit wie möglich zu reduzieren, aber es ist sicherer, auf die Duplizierung zu setzen, wenn Sie keinen besseren Weg finden, um die benötigte Testabdeckung zu erreichen.
Wenn es um den Aufbau Ihrer Pipeline geht, sollten Ihre Komponententests und Scans normalerweise in den CI-Teil Ihrer Pipeline fallen, da sie alle während der Codeerstellung ausgewertet werden können.
Ein- und Ausstiegspunkte : Der gesamte Code empfängt Eingaben und stellt dann eine Ausgabe bereit. Im Grunde geht es beim Unit-Test darum, alles zu testen, was ein Codeteil empfangen kann, und dann müssen Sie sicherstellen, dass er die richtige Ausgabe sendet. Indem Sie alles abfangen, was durch jeden Codeabschnitt im System fließt, reduzieren Sie die Anzahl der Fehler, die bei der Integration als Ganzes wahrscheinlich auftreten, erheblich.
Isolierte Funktionalität : Während der meiste Code auf einer integrierten Ebene arbeitet, gibt es viele Funktionen, die alle Berechnungen intern durchführen. Diese können ausschließlich Unit-Tests unterzogen werden und Teams sollten eine 100-prozentige Unit-Test-Abdeckung für diese Codeteile anstreben. Bei der Arbeit in Microservice-Architekturen, in denen Authentifizierungs- oder Rechnerfunktionen keine Abhängigkeiten aufweisen, bin ich meist auf isolierte Funktionen gestoßen. Das bedeutet, dass sie Unit-Tests unterzogen werden können, ohne dass eine zusätzliche Integration erforderlich ist.
Grenzwertvalidierungen : Code verhält sich gleich, wenn er gültige oder ungültige Argumente empfängt, unabhängig davon, ob er über eine Benutzeroberfläche, eine integrierte API oder direkt über den Code eingegeben wird. Es besteht für Tester keine Notwendigkeit, erschöpfende Szenarien durchzugehen, wenn ein Großteil davon in Unit-Tests abgedeckt werden kann.
Klare Datenpermutationen : Wenn die Dateneingaben und -ausgaben klar sind, ist dieser Code oder diese Komponente ein idealer Kandidat für einen Komponententest. Wenn Sie es mit komplexen Datenpermutationen zu tun haben, ist es am besten, diese auf Integrationsebene anzugehen. Der Grund dafür ist, dass komplexe Daten oft schwer zu simulieren und langsam zu verarbeiten sind und Ihre Codierungspipeline verlangsamen.
Sicherheit und Leistung : Während die meisten Last-, Leistungs- und Sicherheitstests auf Integrationsebene stattfinden, können diese auch auf Einheitenebene getestet werden. Jeder Codeabschnitt sollte in der Lage sein, eine ungültige Authentifizierung, Umleitung oder SQL-/Code-Injection zu verarbeiten und Code effizient zu übertragen. Um diese zu validieren, können Unit-Tests erstellt werden. Schließlich sind die Sicherheit und Leistung eines Systems nur so effektiv wie sein schwächster Teil. Daher ist es ein guter Anfang, sicherzustellen, dass es keine schwachen Teile gibt.
Hierbei handelt es sich um Tests, die in der Regel nach der Bereitstellung Ihres Codes in einer größeren Umgebung ausgeführt werden. Dabei muss es sich jedoch nicht unbedingt um eine permanente Umgebung handeln, und etwas, das Container verwendet, funktioniert genauso gut. Ich habe jedoch gesehen, dass viele Teams in dieser Phase immer noch versuchen, alles zu testen, und dies kann dazu führen, dass sich die Ausführung Ihrer Pipeline sehr in die Länge zieht. Etwas, das nicht besonders gut ist, wenn Sie es jeden Tag regelmäßig in der Produktion bereitstellen möchten.
Daher ist es wichtig, nur die Bereiche zu testen, die Ihre Unit-Tests zufriedenstellend abdecken, und sich gleichzeitig auf Funktionalität und Leistung in Ihrem gesamten Testdesign zu konzentrieren. Einige Designprinzipien, die ich später in diesem Artikel darlege, werden dabei helfen.
Positive Integrationsszenarien : Wir müssen die Integrationspunkte noch automatisieren, um sicherzustellen, dass sie ordnungsgemäß funktionieren. Der Trick besteht jedoch darin, sich nicht zu sehr auf eine umfassende Fehlervalidierung zu konzentrieren, da diese häufig durch bestimmte Ausgaben ausgelöst wird, die einem Unit-Test unterzogen werden können. Konzentrieren Sie sich vielmehr darauf, eine erfolgreiche Integration sicherzustellen.
Testen Sie Backend über Frontend : Wenn möglich, konzentrieren Sie Ihre Automatisierungsbemühungen auf Backend-Komponenten und nicht auf Frontend-Komponenten. Auch wenn der Benutzer das Front-End möglicherweise häufiger verwendet, liegt dort in der Regel nicht der Großteil der funktionalen Komplexität, und Backend-Tests sind viel schneller und daher besser für die Ausführung Ihrer Testautomatisierung.
Sicherheit : Einer der häufigsten Fehler besteht darin, dass Teams sich bei den meisten ihrer Sicherheitstests auf Sicherheitsscans verlassen und dann einige andere kritische Penetrationstests, die an der Software durchgeführt werden, nicht automatisieren. Und obwohl einige Penetrationstests nicht effektiv in einer Pipeline ausgeführt werden können, ist dies bei vielen möglich und sollte aufgrund ihrer Bedeutung automatisiert und regelmäßig ausgeführt werden, insbesondere wenn es um Funktionen geht, die Zugriff, Zahlung oder Datenschutz abdecken. Dies sind Bereiche, die nicht gefährdet werden dürfen und abgedeckt werden sollten.
Wenn es um Automatisierung geht, geht es nicht nur darum, zu verstehen, was automatisiert werden soll, sondern auch, was nicht automatisiert werden sollte. Selbst wenn es Tests gibt, die automatisiert sind, sollten diese nicht immer in Ihren CI/CD-Pipelines landen. Und obwohl das Ziel darin besteht, immer so weit wie möglich nach links zu verschieben und diese Bereiche zu meiden, ist dies bei einigen Architekturen nicht immer möglich und möglicherweise ist eine zusätzliche Validierungsebene erforderlich, um die erforderliche Testabdeckung zu erfüllen.
Das bedeutet nicht, dass Tests nicht automatisiert oder in Pipelines platziert werden sollten, sondern lediglich, dass sie von Ihren CI/CD-Prozessen getrennt und stattdessen täglich als Teil einer geplanten Ausführung und nicht als Teil Ihrer Codebereitstellung ausgeführt werden sollten .
End-to-End-Tests mit hohen Datenanforderungen : Alles, was zum Testen komplexer Datenszenarien erforderlich ist, sollte der Ausführung in einer geeigneten Testumgebung außerhalb einer Pipeline vorbehalten sein. Obwohl diese Tests automatisiert werden können, sind sie oft zu komplex oder zu spezifisch für die reguläre Ausführung in einer Pipeline. Außerdem dauert die Ausführung und Validierung lange, sodass sie nicht ideal für Pipelines sind.
Visuelle Regression : Außerhalb von Funktionstests ist es wichtig, häufig eine visuelle Regression für die Benutzeroberfläche einer Website durchzuführen, um sicherzustellen, dass sie auf verschiedenen Geräten, Browsern und Auflösungen konsistent aussieht. Dies ist ein wichtiger Aspekt des Testens, der oft übersehen wird. Da es sich jedoch nicht um das tatsächliche Funktionsverhalten handelt, ist es oft am besten, dies außerhalb Ihrer zentralen CI/CD-Pipelines auszuführen, obwohl dies immer noch eine Anforderung vor größeren Releases oder UI-Updates ist.
Mutationstests : Mutationstests sind eine fantastische Möglichkeit, die Abdeckung Ihrer Unit-Test-Bemühungen zu überprüfen und zu sehen, was möglicherweise übersehen wurde, indem Sie verschiedene Entscheidungen in Ihrem Code anpassen und sehen, was übersehen wird. Der Prozess ist jedoch recht langwierig und sollte am besten im Rahmen eines Überprüfungsprozesses durchgeführt werden, anstatt Teil Ihrer Pipelines zu sein.
Belastungs- und Stresstests : Während es wichtig ist, die Leistung verschiedener Teile des Codes zu testen, möchten Sie ein System in einer Pipeline keiner Form von Last oder Stress aussetzen. Um diese Tests optimal durchführen zu können, benötigen Sie eine spezielle Umgebung und spezifische Bedingungen, die die Grenzen Ihrer zu testenden Anwendung ausloten. Nicht das, was Sie als Teil Ihrer Pipelines tun möchten.
Es ist also klar, dass wir einen Shift-Left-Ansatz brauchen, der sich stark auf Unit-Tests mit hoher Abdeckung stützt, aber auch auf eine gute Auswahl an Tests, die alle Bereiche abdecken, um die Qualität zu erreichen, die wahrscheinlich benötigt wird. Es scheint jedoch immer noch viel zu sein und es besteht immer das Risiko, dass die Ausführung der Pipelines immer noch eine beträchtliche Zeit in Anspruch nehmen kann, insbesondere auf CD-Ebene, wo die zeitintensiveren Integrationstests nach der Code-Bereitstellung ausgeführt werden.
Es gibt jedoch auch eine Art und Weise, wie Sie Ihre Tests gestalten, die dabei hilft, diese effektiv zu gestalten. Unnötige Tests zu automatisieren ist eine große Zeitverschwendung, aber das Gleiche gilt auch für ineffizient geschriebene Tests. Das größte Problem hierbei besteht darin, dass Tester oft kein vollständiges Verständnis für die Effizienz ihrer Testautomatisierung haben und sich auf die Ausführung konzentrieren, anstatt nach der prozessor- und speichereffizientesten Methode dafür zu suchen.
Das Geheimnis dafür, dass alle Tests funktionieren, ist Einfachheit. Automatisierte Tests sollten nicht kompliziert sein. Führen Sie eine Aktion aus und erhalten Sie eine Antwort. Deshalb ist es wichtig, sich bei der Gestaltung Ihrer Tests daran zu halten. Die folgenden Attribute sind wichtige Dinge, die Sie beim Entwerfen Ihrer Tests beachten sollten, um sie sowohl einfach als auch leistungsfähig zu halten.
Sie denken vielleicht nicht, dass die Benennung von Tests wichtig ist, aber sie ist wichtig, wenn es um die Wartbarkeit der Tests geht. Während Testnamen möglicherweise nichts mit der Testfunktionalität oder der Ausführungsgeschwindigkeit zu tun haben, helfen sie anderen, zu wissen, was der Test bewirkt. Wenn also bei einem Test Fehler auftreten oder etwas repariert werden muss, beschleunigt dies den Wartungsprozess erheblich, und das ist wichtig, wenn Sie die vielen tausend Tests absolvieren, die Ihre Pipeline voraussichtlich durchführen wird.
Tests dienen nicht nur dazu, sicherzustellen, dass Ihr Code funktioniert, sondern dienen auch der Dokumentation. Allein durch einen Blick auf die Unit-Tests sollten Sie in der Lage sein, auf das Verhalten Ihres Codes zu schließen. Darüber hinaus können Sie bei fehlgeschlagenen Tests genau sehen, welche Szenarien Ihre Erwartungen nicht erfüllt haben.
Der Name Ihres Tests sollte aus drei Teilen bestehen:
Durch die Verwendung dieser Namenskonventionen stellen Sie sicher, dass Sie leicht erkennen können, was ein Test oder Code tun soll, und beschleunigen gleichzeitig Ihre Fähigkeit, Ihren Code zu debuggen.
Die Lesbarkeit ist einer der wichtigsten Aspekte beim Schreiben eines Tests. Während es möglicherweise möglich ist, einige Schritte zu kombinieren und die Größe Ihres Tests zu reduzieren, besteht das Hauptziel darin, den Test so lesbar wie möglich zu machen. Ein gängiges Muster beim Schreiben einfacher Funktionstests ist „Anordnen, Handeln, Behaupten“. Wie der Name schon sagt, besteht es aus drei Hauptaktionen:
Indem Sie jede dieser Aktionen innerhalb des Tests klar trennen, heben Sie Folgendes hervor:
Dies erleichtert das Schreiben, Verstehen und Warten von Tests und verbessert gleichzeitig ihre Gesamtleistung, da jedes Mal einfache Vorgänge ausgeführt werden.
Allzu oft versuchen die Leute, die automatisierte Tests schreiben, komplexe Codierungstechniken zu nutzen, die auf mehrere unterschiedliche Verhaltensweisen eingehen können, aber in der Welt des Testens führt dies lediglich zu einer Erhöhung der Komplexität. Tests, die mehr Informationen enthalten, als zum Bestehen des Tests erforderlich sind, haben ein höheres Fehlerrisiko und können die Absicht des Tests weniger klar machen. Wenn Sie beispielsweise zusätzliche Eigenschaften für Modelle festlegen oder Werte ungleich Null verwenden, wenn diese nicht erforderlich sind, beeinträchtigt dies nur das, was Sie beweisen möchten. Beim Schreiben von Tests möchten Sie sich auf das Verhalten konzentrieren. Um dies zu erreichen, sollte die Eingabe, die Sie verwenden, so einfach wie möglich sein.
Wenn Sie Logik in Ihre Testsuite einführen, erhöht sich die Wahrscheinlichkeit, dass durch menschliches Versagen oder falsche Ergebnisse ein Fehler entsteht, dramatisch. Der letzte Ort, an dem Sie einen Fehler finden möchten, ist Ihre Testsuite, da Sie ein hohes Maß an Vertrauen in die Funktionsfähigkeit Ihrer Tests haben sollten. Andernfalls werden Sie ihnen nicht vertrauen und sie bieten keinen Mehrwert.
Vermeiden Sie beim Schreiben Ihrer Tests die manuelle Verkettung von Zeichenfolgen und logische Bedingungen wie if, while, for oder switch, da Sie so unnötige Logik vermeiden können. Ebenso sollte jede Form der Berechnung vermieden werden – Ihr Test sollte auf einer leicht identifizierbaren Eingabe und einer klaren Ausgabe basieren – andernfalls kann es aufgrund bestimmter Kriterien leicht zu Unstimmigkeiten kommen – und außerdem erhöht sich der Wartungsaufwand, da sich die Testlogik ändert, wenn sich die Codelogik ändert wird sich auch ändern müssen.
Ein weiterer wichtiger Punkt hierbei ist, sich daran zu erinnern, dass Pipeline-Tests schnell ausgeführt werden sollten und die Logik tendenziell mehr Verarbeitungszeit kostet. Ja, es mag auf den ersten Blick unbedeutend erscheinen, aber bei mehreren Hundert Tests kann sich das summieren.
Viele Tester könnten dies missbilligen, da der Gedanke, viele Mocks und Stubs zu verwenden, als Vermeidung des echten integrierten Verhaltens einer Anwendung angesehen werden kann. Dies gilt für End-to-End-Tests, die Sie dennoch automatisieren möchten, ist jedoch nicht ideal für die Pipeline-Ausführung. Dies verlangsamt nicht nur die Pipeline-Ausführung, sondern führt auch zu unregelmäßigen Testergebnissen, da externe Funktionen nicht betriebsbereit sind oder nicht mit Ihren Änderungen synchronisiert sind.
Der beste Weg, um sicherzustellen, dass Ihre Testergebnisse zuverlässiger sind, und Ihnen gleichzeitig eine bessere Kontrolle über Ihren Testaufwand zu ermöglichen und die Abdeckung zu verbessern, besteht darin, Mocking in Ihr Test-Framework zu integrieren und sich auf Stubs zu verlassen, um komplexe Datenmuster abzufangen, auf die eine externe Funktion zugreift TU es für dich.
In Unit-Testing-Frameworks wird vor jedem einzelnen Unit-Test innerhalb Ihrer Testsuite eine Setup-Funktion aufgerufen. Für jeden Test gelten im Allgemeinen unterschiedliche Anforderungen, um den Test zum Laufen zu bringen. Leider zwingt Sie das Setup dazu, für jeden Test genau die gleichen Anforderungen zu verwenden. Auch wenn manche dies als nützliches Tool ansehen, führt es im Allgemeinen zu überladenen und schwer lesbaren Tests. Wenn Sie für Ihre Tests ein ähnliches Objekt oder einen ähnlichen Zustand benötigen, verwenden Sie lieber eine vorhandene Hilfsmethode, anstatt die Setup- und Teardown-Attribute zu nutzen.
Dies wird helfen, indem Folgendes eingeführt wird:
Bei der Einführung mehrerer Behauptungen in einen Testfall kann nicht garantiert werden, dass alle ausgeführt werden. Dies liegt daran, dass der Test wahrscheinlich am Ende einer früheren Behauptung fehlschlägt und die restlichen Tests nicht ausgeführt werden. Sobald eine Behauptung in einem Komponententest fehlschlägt, gelten die weiteren Tests automatisch als fehlgeschlagen, auch wenn dies nicht der Fall ist. Dies führt dann dazu, dass der Ort des Fehlers unklar ist, was ebenfalls zu einer Zeitverschwendung beim Debuggen führt.
Versuchen Sie beim Schreiben Ihrer Tests, nur eine Behauptung pro Test einzuschließen. Dies trägt dazu bei, dass leicht genau festgestellt werden kann, was fehlgeschlagen ist und warum. Teams können leicht den Fehler machen, so wenige Tests wie möglich zu schreiben, die eine hohe Abdeckung erreichen, aber am Ende führt dies nur dazu, dass die zukünftige Wartung zu einem Albtraum wird.
Dies hängt auch mit der Entfernung von Testduplikaten zusammen. Sie möchten während der Pipeline-Ausführung keine Tests wiederholen. Wenn Sie die Tests besser sichtbar machen, kann das Team sicherstellen, dass dieses Ziel erreicht werden kann.
Obwohl Testcode möglicherweise nicht in einer Produktionsumgebung ausgeführt wird, sollte er genauso behandelt werden wie jeder andere Code. Und das bedeutet, dass es regelmäßig aktualisiert und gewartet werden sollte. Schreiben Sie keine Tests und gehen Sie davon aus, dass alles erledigt ist. Sie müssen viel Arbeit investieren, um Ihre Tests funktionsfähig und fehlerfrei zu halten und gleichzeitig alle Bibliotheken und Abhängigkeiten auf dem neuesten Stand zu halten. Sie möchten keine technischen Schulden in Ihrem Code haben – nehmen Sie sie auch nicht in Ihren Tests auf.
Okay, letzteres ist weniger ein tatsächliches Designprinzip als vielmehr ein Tipp für gutes Testschreiben. Wie bei allen Dingen, die mit dem Codieren zu tun haben, reicht es nicht aus, die Theorie zu kennen, und es erfordert Übung, um gut zu werden und eine Gewohnheit zu entwickeln. Daher wird es einige Zeit dauern, bis diese Testpraktiken richtig sind und sich natürlich anfühlen. Die Fähigkeit, einen richtigen Test zu schreiben, wird jedoch völlig unterbewertet und steigert die Qualität des Codes erheblich, so dass sich der Aufwand und die zusätzlichen Anstrengungen auf jeden Fall lohnen.
Wie Sie sehen, kann die Testautomatisierung in Ihrem gesamten Stack weiterhin innerhalb Ihrer Pipeline funktionieren und Ihnen ein hohes Maß an Regressionsabdeckung bieten, ohne Ihre Pipeline unnötig zu unterbrechen oder zu verlangsamen. Um effektiv zu funktionieren, ist jedoch ein gutes Testdesign erforderlich. Daher müssen die Unit- und automatisierten Tests gut geschrieben sein, um den größtmöglichen Nutzen zu erzielen.
Eine gute DevOps-Teststrategie erfordert eine solide Basis an Unit-Tests, um den Großteil der Abdeckung mit Mock-Ups zu gewährleisten und so den Rest des Automatisierungsaufwands voranzutreiben, sodass nur noch ein paar automatisierte End-to-End-Tests erforderlich sind, um sicherzustellen, dass alles funktioniert Bestellen Sie und geben Sie Ihrem Team die Gewissheit, dass die Pipeline-Tests seine Qualitätsanforderungen erfolgreich erfüllen werden.
Das Schreiben für InfoQ hat viele Türen geöffnet und die Karrierechancen erhöht Für mich. Ich konnte mich intensiv mit Experten und Vordenkern austauschen, um mehr über die von mir behandelten Themen zu erfahren. Und ich kann meine Erkenntnisse auch an die breitere Tech-Community weitergeben und verstehen, wie die Technologien in der realen Welt eingesetzt werden.
Ich habe das Mitwirkendenprogramm von InfoQ Anfang dieses Jahres entdeckt und es seitdem genossen! Das Peer-to-Peer-Review-System von InfoQ bietet mir nicht nur eine Plattform, auf der ich meine Erkenntnisse mit einer globalen Community von Softwareentwicklern teilen kann, sondern hat auch mein Schreiben erheblich verbessert . Wenn Sie nach einem Ort suchen, an dem Sie Ihr Software-Know-how teilen können, beginnen Sie mit der Mitarbeit bei InfoQ.
Ich habe angefangen, Nachrichten für die InfoQ .NET-Warteschlange zu schreiben, um auf dem neuesten Stand der Technik zu bleiben, aber ich habe so viel mehr daraus gemacht. Ich habe sachkundige Leute kennengelernt, weltweite Sichtbarkeit erlangt und meine Schreibfähigkeiten verbessert.
Redakteur für InfoQ zu werden war eine der besten Entscheidungen meiner Karriere . Es hat mich herausgefordert und mir in vielerlei Hinsicht geholfen, zu wachsen . Wir würden uns über mehr Leute freuentrete unserem Team bei.
InfoQ sucht einen Chefredakteur in Vollzeit dem internationalen, stets remote arbeitenden Team von C4Media beizutreten. Entdecken Sie mit uns die innovativsten Technologien unserer Zeit, arbeiten Sie mit den besten Software-Experten der Welt zusammen und helfen Sie mehr als 1,6 Millionen Entwicklerteams bei der Einführung neuer Technologien und Praktiken, die die Grenzen dessen erweitern, was Software und Teams leisten können!
Jeden Dienstag wird eine Zusammenfassung der Inhalte der letzten Woche auf InfoQ verschickt. Treten Sie einer Community von über 250.000 erfahrenen Entwicklern bei. Sehen Sie sich ein Beispiel an
Wir schützen Ihre Privatsphäre.
Sie müssen ein InfoQ-Konto registrieren oder sich anmelden oder anmelden, um Kommentare zu posten. Aber hinter der Registrierung steckt noch viel mehr.
Holen Sie das Beste aus dem InfoQ-Erlebnis heraus.
Zulässiges HTML: a,b,br,blockquote,i,li,pre,u,ul,p
Zulässiges HTML: a,b,br,blockquote,i,li,pre,u,ul,p
Zulässiges HTML: a,b,br,blockquote,i,li,pre,u,ul,p
Treten Sie einer Expertengemeinschaft bei.Ein- und AusstiegspunkteIsolierte FunktionalitätGrenzwertvalidierungenKlare DatenpermutationenSicherheit und LeistungPositive IntegrationsszenarienTesten Sie Backend über FrontendSicherheitEnd-to-End-Tests mit hohen DatenanforderungenVisuelle RegressionMutationstestsBelastungs- und StresstestsCraig Risihat viele Türen geöffnet und die Karrierechancen erhöhtVivian HuDas Peer-to-Peer-Review-System von InfoQ hat mein Schreiben erheblich verbessertOghenewede Emenierlangte weltweite Sichtbarkeit und verbesserte meine SchreibfähigkeitenEdin Kapićbeste Entscheidungen meiner Karrierehat mir in vielerlei Hinsicht geholfen, zu wachsentrete unserem Team beiThomas Bettshauptamtlicher ChefredakteurDas InfoQHolen Sie das Beste aus dem InfoQ-Erlebnis heraus.