banner

Nachricht

Oct 03, 2023

Eine einfachere Testpyramide: Holen Sie das Beste aus Ihren Tests heraus

InfoQ-Homepage-Artikel Eine einfachere Testpyramide: Holen Sie das Beste aus Ihren Tests heraus

Dieser Artikel auf Japanisch

10. April 2023 10 Minuten Lesezeit

von

Tyson Gern

rezensiert von

Matt Campbell

Entwickler verwenden viele verschiedene Bezeichnungen, um ihre automatisierten Tests zu beschreiben (Einheit, Integration, Akzeptanz, Komponente, Service, End-to-End, UI, Datenbank, System, Funktion oder API). Jede dieser Bezeichnungen hat eine andere semantische Bedeutung und beschreibt entweder den Umfang des Tests, die Arten von Aktionen, die der Test durchführt, den Probanden des Tests oder die Mitarbeiter des Probanden. Normalerweise sind wir uns nicht einig darüber, was die einzelnen Bezeichnungen bedeuten, und die Diskussionen über ihre Definition sind in der Regel sinnlos.

Anstatt darüber zu streiten, welche Bezeichnungen verwendet werden sollen und wie man sie definiert, habe ich es als hilfreicher empfunden, für die Bezeichnung jedes Tests eines von zwei Adjektiven zu verwenden: langsam oder schnell. Diese Bezeichnungen können bei der Entscheidung über die Zusammensetzung einer Testsuite ebenso nützlich sein und ermöglichen Entwicklern gleichzeitig eine objektive Klassifizierung von Tests ohne unproduktive Argumente.

Programmieren, implementieren und skalieren Sie Java nach Ihren Wünschen. Microsoft Azure unterstützt Ihre Arbeitslast mit zahlreichen Auswahlmöglichkeiten, unabhängig davon, ob Sie an einer Java-App, einem App-Server oder einem Framework arbeiten. Erfahren Sie mehr.

Die Wahl der Testbezeichnungen hat einen wichtigen Einfluss auf den Aufbau einer Testsuite. Entwickler verwenden sie, um zu wissen, wann sie einen Test für ein bestimmtes Verhalten schreiben müssen, um zu wissen, welche Art von Test sie schreiben müssen, und um die Ausgewogenheit der Testsuite als Ganzes zu beurteilen. Wenn wir das falsch machen, erhalten wir am Ende eine Testsuite, die entweder keine genaue Abdeckung bietet oder die Abdeckung zu inakzeptablen Kosten bereitstellt.

Wann sollten Sie einen Test für einen bestimmten Teil des Produktionscodes schreiben? Entwickler, die wie ich Extreme Programming (XP) oder Test Driven Development (TDD) praktizieren, beantworten diese Frage oft mit „immer“. Allerdings sollte nicht jeder Code automatisch getestet werden. Wägen Sie für jeden vorgeschlagenen Test zunächst die Kosten für das Schreiben des Tests gegen den Nutzen ab.

Ich plädiere nicht gegen das Schreiben von Tests. Tatsächlich handelt es sich bei den meisten Tests um eine schnelle Überprüfung, und die Antwort lautet „Ja“. Diese Prüfung ist jedoch nützlich, insbesondere wenn die Ausführung eines Tests langsam ist, das Schreiben langsam ist oder die Wartung schwierig ist. Stellen Sie sich in diesen Fällen ein paar Fragen.

Ist der Test aufgrund einer Designentscheidung kostspielig? Kann der Code umgestaltet werden, um Tests besser zu ermöglichen? Ihre Tests sind die ersten Konsumenten Ihres Produktionscodes. Durch die einfachere Testbarkeit von Code wird die Nutzung häufig erleichtert und die Qualität Ihrer Codebasis verbessert.

Ist der Test aufgrund des Testansatzes kostspielig? Würde ein anderer Testansatz das Schreiben dieses Tests erleichtern? Erwägen Sie die Verwendung von Testdoppeln wie Fälschungen oder Scheinen anstelle von Mitarbeitern. Wenn Ihre Tests ein kompliziertes Setup erfordern, extrahieren Sie dieses in ein Testszenario, das zwischen den Tests wiederverwendet werden kann.

Achten Sie darauf, Test-Doubles nicht zu häufig einzusetzen, da diese nicht so viel Vertrauen vermitteln wie echte Mitarbeiter. Manchmal ist dieser Vertrauensverlust die einfachere Einrichtung, die kürzere Testdauer oder die höhere Zuverlässigkeit wert. Wenn Sie sich jedoch zu sehr auf Testdubletten verlassen, können Ihre Tests an Ihre Implementierung gekoppelt werden, was zu einer Testsuite führt, die wenig Vertrauen bietet und das Refactoring behindert.

Ist der Test kostspielig, weil das Verhalten von Natur aus schwer zu testen ist? Wenn ja, bedenken Sie die Bedeutung der Funktion, die Sie testen. Wenn es sich um eine wichtige Funktion bei der Zahlungsabwicklung handelt, kann sich der Test lohnen. Wenn es sich um einen eigenartigen Randfall in Ihrer Anzeigelogik handelt, sollten Sie noch einmal darüber nachdenken, ob Sie den Test schreiben möchten oder nicht.

Ist der Test kostspielig, weil er unvorhersehbar fehlschlägt? Wenn dies der Fall ist, müssen Sie es entfernen, es umschreiben, um es zuverlässiger zu machen, oder es vom Rest Ihrer Testsuite trennen. Damit eine Testsuite nützliches Feedback liefern kann, müssen Sie sicher sein, dass Testfehler unerwünschtes Verhalten darstellen. Wenn Sie feststellen, dass ein Test notwendig ist und nicht vorhersehbar gemacht werden kann, verschieben Sie ihn in eine andere Testsuite, die weniger häufig ausgeführt wird.

Um die Entscheidung zu erleichtern, wann und welche Art von Test geschrieben werden soll, platzieren Entwickler häufig Testetiketten auf einer Testpyramide, um zu verdeutlichen, wie wichtig es ist, mehr von einem Testtyp zu haben als von einem anderen.

Angesichts der vielen verschiedenen Bezeichnungen, die zur Beschreibung von Tests verwendet werden, sieht jede Testpyramide ein wenig anders aus als die anderen. Versuchen Sie, eine Bildersuche nach „Testpyramide“ durchzuführen, und Sie werden auf der ersten Ergebnisseite nur wenige doppelte Pyramiden finden. In jeder Pyramide befinden sich in der Regel unten kostengünstige Unit-Tests, oben kostenintensive Systemtests und in der Mitte mehrere Schichten mittelkostenintensiver Tests.

Bevor ein Team von der Testpyramide profitieren kann, muss das Team entscheiden, welche Labels in die Testpyramide aufgenommen werden sollen, welche Definition jedes Label hat und in welcher Reihenfolge die Labels in die Pyramide aufgenommen werden sollen.

Dies ist oft eine umstrittene Entscheidung, da jeder Entwickler in einem Team dazu neigt, unterschiedliche Bezeichnungen zur Beschreibung von Tests zu verwenden, und es keine breite Einigkeit darüber gibt, was die einzelnen Bezeichnungen bedeuten. Tatsächlich enthält fast jede Testpyramide am unteren Ende Unit-Tests, es besteht jedoch große Uneinigkeit darüber, was das Wort „Einheit“ bedeutet. Diese Meinungsverschiedenheit verringert den Nutzen der Testpyramide, da sich die Diskussionen eher um die Bezeichnungen als um die Reduzierung der Kosten der Testsuite drehen.

Die Geschwindigkeit trägt tendenziell am meisten zu den Kosten einer Testsuite bei. Um schnelles Feedback zu erhalten, sollten Entwickler die Testsuite mehrmals pro Stunde ausführen, sodass selbst eine geringfügige Verlängerung der zum Ausführen der Suite benötigten Zeit im Laufe der Zeit zu langen Wartezeiten führen kann.

Die Zeit, die damit verbracht wird, auf die Ausführung der Tests zu warten, ist unproduktive Zeit. Wenn eine Testsuite sehr langsam ist (die Ausführung dauert länger als fünf Minuten), arbeiten Entwickler häufig an anderen Aufgaben, während der Test ausgeführt wird. Dieser Aufgabenwechsel ist schädlich, da er den Fokus verringert und dazu führt, dass der Entwickler den Kontext verliert. Sobald die langsame Testsuite abgeschlossen ist, muss sich der Entwickler zusätzliche Zeit nehmen, um den Kontext wiederherzustellen, bevor er mit seiner ursprünglichen Aufgabe fortfahren kann.

Wenn man sich auf die Testgeschwindigkeit konzentriert, entsteht eine einfachere Testpyramide.

Diese Pyramide vermittelt die klare Botschaft, dass eine Testsuite so viele schnelle Tests wie möglich und gerade genug langsame Tests enthalten sollte, um das gewünschte Verhalten vollständig abzudecken. Es vermittelt die gleiche Botschaft wie die häufigeren (und komplizierteren) Testpyramiden, ist für Entwickler jedoch viel einfacher zu verstehen und zu vereinbaren.

Während sich verschiedene Entwickler möglicherweise nicht darüber einig sind, wo ein bestimmter Test in einer gemeinsamen Testpyramide platziert werden soll, ist es leicht zu wissen, wo ein bestimmter Test in die obige Pyramide passt. Die Teams müssen sich lediglich darauf einigen, was ein schneller und was ein langsamer Test ist. Während der Schwellenwert je nach Geschäftsdomäne, Sprache oder Framework unterschiedlich sein kann, kann die Geschwindigkeit von Tests objektiv gemessen werden.

Testsuiten beginnen immer schnell, bleiben aber selten so. Mit der Zeit werden weitere Tests hinzugefügt und die Entwicklertoleranz gegenüber einer langsamen Testsuite steigt. Viele Entwickler erkennen nicht, dass eine schnelle Testsuite möglich ist, da sie noch nie in einer Codebasis gearbeitet haben, in der die Testsuite schnell bleibt.

Um eine Testsuite schnell zu halten, ist Disziplin erforderlich. Entwickler müssen jedes Mal, wenn sie eine Testsuite erweitern, genau prüfen und sich darüber im Klaren sein, welch große Vorteile bereits eine geringfügige Verkürzung der Länge mit sich bringt. Wenn beispielsweise ein Mitglied eines Teams aus 6 Entwicklern 4 Stunden damit verbringt, die Tests um 10 Sekunden zu beschleunigen, amortisiert sich diese Investition in nur sechs Wochen (vorausgesetzt, Entwickler führen Tests einmal pro Stunde an einem Arbeitstag durch).

Wenn diese Option nicht aktiviert ist, nimmt die Länge einer Testsuite mit der Zeit exponentiell zu. Das heißt, die Länge nimmt proportional zur aktuellen Dauer zu. Wenn die Suite in 10 Sekunden ausgeführt wird, könnte es für einen Entwickler schwierig sein, nur eine Sekunde zum Build hinzuzufügen, aber sobald die Testsuite auf 3 Minuten angewachsen ist, merkt er es möglicherweise nicht einmal mehr.

Eine Methode, um exponentielles Wachstum zu verhindern, besteht darin, eine feste Grenze für die Länge Ihrer Testsuite festzulegen: Lassen Sie den Build fehlschlagen, wenn die Ausführung Ihrer Testsuite beispielsweise länger als eine Minute dauert. Wenn ein Testlauf zu lange dauert, schlägt der Build fehl und der Entwickler muss sich etwas Zeit nehmen, um die Tests zu beschleunigen, bevor er fortfahren kann. Reparieren Sie den Build nicht, indem Sie einfach dieses Limit erhöhen. Nehmen Sie sich lieber die Zeit, zu verstehen, warum die Tests langsam sind und wie Sie sie beschleunigen können.

Testcode muss mit der gleichen Sorgfalt und Prüfung behandelt werden wie Produktionscode. Refaktorieren Sie kontinuierlich, um Ihren Testcode gut strukturiert und schnell zu halten und so die Kosten für die Wartung und den Betrieb Ihrer Testsuite zu minimieren. Beachten Sie, dass Refactoring-Tests weder das Verhalten des Testcodes noch des Produktionscodes verändern sollten. Vielmehr sollte Ihr Code dadurch besser lesbar, wartbarer und schneller ausführbar sein.

Wenn Sie ein paar langsame Tests nicht vermeiden können, fügen Sie sie einer separaten Testsuite hinzu. Diese langsame Testsuite ist nicht dafür gedacht, so oft ausgeführt zu werden wie Ihre Haupttestsuite, sondern soll eine zusätzliche Abdeckung bieten. Es sollte den Build-Prozess nicht blockieren, aber regelmäßig ausgeführt werden, um sicherzustellen, dass das getestete Verhalten weiterhin ordnungsgemäß funktioniert.

Es ist noch nicht zu spät, Ihren Ansatz zu ändern, wenn Sie zur Gestaltung Ihrer aktuellen Testsuite eine andere Testpyramide verwendet haben. Wenn Sie einer komplizierteren Testpyramide gefolgt sind, ist es wahrscheinlich, dass viele Ihrer Tests die Bezeichnungsnamen Ihrer Testpyramide enthalten.

Nehmen Sie sich als ersten Schritt etwas Zeit, um Ihre Tests umzubenennen. Die neuen Testnamen sollten das getestete Verhalten widerspiegeln und nicht die Testbezeichnung. Beispielsweise können Sie UserIntegrationTest in UserAuthenticationTest oder RegistrationApiTest in AddPaidUserTest umbenennen.

Während dieses Vorgangs werden Sie wahrscheinlich auf einige Kollisionen zwischen den neuen Namen stoßen. Diese Kollisionen sind eine Warnung, dass Sie möglicherweise mehrere Tests haben, die dasselbe Verhalten abdecken. Nehmen Sie sich etwas Zeit, diese Tests zu verschieben, zu kombinieren, umzubenennen oder zu entfernen, um die Duplikate zu beheben.

Sobald Ihre Tests umbenannt wurden, organisieren Sie die Testverzeichnisstruktur neu, um Tests nach Verhalten zu gruppieren. Diese Organisation hält Tests, die sich gleichzeitig ändern, in Ihrer Codebasis nahe beieinander und hilft Ihnen dabei, neue Tests zu erkennen, die doppeltes Verhalten abdecken.

Eine langsame Testsuite muss sofort behoben werden. Legen Sie sofort ein Limit für die Dauer der Testsuite fest, damit sie nicht langsamer wird. Fügen Sie als Nächstes einige Instrumente hinzu, die Ihnen dabei helfen, die langsamsten Tests zu finden, indem Sie die Ausführungszeit für jeden Test oder jede Testgruppe auflisten. Während dieses Vorgangs werden Sie wahrscheinlich auf einige Tests stoßen, die sich leicht beschleunigen lassen.

Sobald Sie diese behoben haben, bleibt eine weitere Gruppe langsamer Tests übrig, die schwieriger zu verbessern sind. Trennen Sie Ihre schnellen Tests, damit Sie sie getrennt von den verbleibenden langsamen Tests ausführen können. Dadurch erhalten Sie bei einigen Testläufen sofort einen Geschwindigkeitsschub, der Ihnen mehr Zeit für Verbesserungen verschafft.

Nehmen Sie sich regelmäßig Zeit, um Ihren Test zu beschleunigen. Untersuchen Sie, ob das von diesen langsamen Tests abgedeckte Verhalten durch schnellere Tests abgedeckt werden kann (oder bereits abgedeckt wird). Ein häufiges Beispiel hierfür ist die Abdeckung vieler Randfälle mit Tests, die einen Browser steuern. Die Verwendung eines Browsers zum Ausführen von Tests ist zeitintensiv und die Verhaltensweisen können häufig durch Tests auf niedrigerer Ebene abgedeckt werden, die tendenziell schneller ausgeführt werden.

Nehmen Sie sich vor Ihrer nächsten Diskussion darüber, ob Sie beispielsweise einen Systemtest oder einen Integrationstest schreiben sollen, eine Minute Zeit zum Nachdenken. Sie werden wahrscheinlich feststellen, dass der Unterschied zwischen den beiden kaum eine Rolle spielt. Wenn Ihr Ziel darin besteht, hohes Vertrauen zu schaffen und gleichzeitig die Kosten zu minimieren, dann geht es bei Ihrer Argumentation eigentlich darum, wie Sie das gewünschte Verhalten mit möglichst geringen Kosten testen können. Lenken Sie die Diskussion in diese Richtung und Sie werden ein produktiveres Ergebnis erzielen.

Anstatt sich auf Testetiketten zu konzentrieren, konzentrieren Sie sich auf das Wesentliche: Schreiben Sie schnelle Tests. Wenn Ihr Test langsam ist, machen Sie ihn schneller. Wenn dies nicht möglich ist, versuchen Sie, mit einigen Tests mit geringerem Umfang die gleiche Abdeckung zu erreichen. Wenn dies fehlschlägt, fragen Sie sich, ob der Nutzen, den der Test bietet, die erheblichen Kosten eines langsamen Tests wert ist. Wenn es sich lohnt, sollten Sie erwägen, Ihre langsamen Tests in eine separate Testsuite zu verlagern, die den Build nicht blockiert.

Folgen Sie dieser neuen Testpyramide und konzentrieren Sie sich auf die Testgeschwindigkeit, um Ihre Testsuite schnell und Ihr Vertrauen hoch zu halten.

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

von Joan Comas,

von Joan Comas,

Ihre Nachricht wartet auf Moderation. Vielen Dank für Ihre Teilnahme an der Diskussion.

Vielen Dank für diesen sehr ausführlichen Artikel. Ich möchte hinzufügen, dass ich auch den Return of Investment jedes Tests bewerte. Insbesondere habe ich die Notwendigkeit eines Tests für Klassen in Frage gestellt, die eine einzige Sache tun, die wir schon immer tun. Ich finde zum Beispiel keinen ROI beim Testen von Folgendem: – Beim Hinzufügen einer Entität in einem Repository wird die Entität in der Datenbank gespeichert. – Beim Aufrufen einer Send()-Methode einer Klasse, die Daten über http senden soll, wird die Daten werden über http gesendet. – Wenn eine Publish()-Methode einer Klasse aufgerufen wird, die ein Ereignis in einer Warteschlange veröffentlichen soll, wird das Ereignis in der Warteschlange veröffentlicht. Diese Repository-Clients und -Herausgeber sollten niemals tatsächliche Geschäftsregeln enthalten. Und ihre Funktionalität dürfte heutzutage trivial sein. Ja, einige SQL-Abfragen werden komplexer sein und es wird Transaktionen und dergleichen geben, aber dann geht es darum, eine Infrastruktur dafür zu schaffen, und DAS ist diejenige, die an einem einzigen Ort ordnungsgemäß getestet wird. Darüber hinaus habe ich Stellen Sie die Notwendigkeit eines „Tests zum Verboten“ in Frage, bei dem Entwickler Tests schreiben, um sicherzustellen, dass keine Abhängigkeiten verwendet werden. Und ich habe viel zu viele gesehen. Abschließend möchte ich noch erwähnen, dass Sie den Code, wenn möglich, nach Features organisieren (wie es bei Vertical Slice und DDD der Fall ist), damit die Gruppe von Tests, die ihn abdecken, isoliert ausgeführt werden kann. spart viel Zeit. Bei der Erstellung einer schnellen Testsuite geht es nicht nur um langsame/schnelle Tests, sondern auch um die Isolierung von Tests. Heutzutage gibt es Tools, mit denen nur betroffene Tests ausgeführt werden können. Nutzen Sie sie also und sparen Sie noch mehr Zeit. Auf diese Weise müssen Entwickler nicht das Bedürfnis verspüren, wichtige langsame Tests nur aus Zeitgründen zu kürzen.

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.Tyson Gernhat 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.von Joan Comas
AKTIE