11 Best Practices für Unit-Tests

Ein Mann arbeitet am Notebook mit 2 Monitoren, die ihn unterstützen.

Autoren

Phill Powell

Staff Writer

IBM Think

Ian Smalley

Staff Editor

IBM Think

Was sind Best Practices für Unit-Tests?

Best Practices für Unit-Tests unterstützen das Schreiben von Unit-Tests, die unabhängig voneinander isoliert ausgeführt werden und deterministische Konsistenzmerkmale aufweisen.

Gute Komponententests spiegeln die testgetriebene Entwicklung (TDD) wider und verwenden Mock-Objekte und Stubs, um die Isolierung zu unterstützen. Best Practices unterstützen auch kontinuierliche Integration und automatisierte Tests.

Was sind Komponententests?

Unter den verschiedenen Arten von Tests bieten Unit-Tests eine nahezu mikroskopische Ansicht einer Codeeinheit, der kleinsten einzelnen Komponente, die durch Softwaretests bewertet wird. Die wichtigste Voraussetzung für ordnungsgemäße Unit-Tests ist die Isolierung, damit die Funktionen der Komponente effektiv bewertet werden können.

Zu den Vorteilen von Unit-Tests zählen die Beschleunigung des Softwareentwicklungsprozesses durch Automatisierung und die Einsparung von Arbeitskosten durch frühzeitiges Debugging im Softwareentwicklungslebenszyklus (SDLC). Solches Debugging unterstützt die Einhaltung aller während der Entwicklung vorgenommenen Codeänderungen und verbessert die Codequalität insgesamt.

Komponententest-Frameworks helfen Testern, Tests an einzelnen Einheiten durchzuführen und insgesamt eine stärkere Codebasis aufzubauen. Ein Test gilt als bestanden, wenn ein Test einen bestimmten Codeabschnitt überprüft und feststellt, dass der Test ordnungsgemäß ausgeführt wird und alle zugehörigen Überprüfungen (auch Assertions genannt) erfolgreich durchgeführt wurden. Die bestandenen Tests zeigen, dass sich das Gerät wie erwartet verhält.

Die neuesten Tech-News – von Experten bestätigt

Bleiben Sie mit dem Think-Newsletter über die wichtigsten – und faszinierendsten – Branchentrends in den Bereichen KI, Automatisierung, Daten und darüber hinaus auf dem Laufenden. Weitere Informationen finden Sie in der IBM Datenschutzerklärung.

Vielen Dank! Sie haben ein Abonnement abgeschlossen.

Ihr Abonnement wird auf Englisch geliefert. In jedem Newsletter finden Sie einen Abmeldelink. Hier können Sie Ihre Abonnements verwalten oder sich abmelden. Weitere Informationen finden Sie in unserer IBM Datenschutzerklärung.

Was sind Abhängigkeiten?

Unit-Tests sind ein vielschichtiges Thema mit verschiedenen Aspekten, die einer Erläuterung bedürfen. Einer dieser Bereiche betrifft Abhängigkeiten. Im Zusammenhang mit Unit-Tests beziehen sich Abhängigkeiten auf externe Dienste oder Komponenten, die eine Codeeinheit benötigt, um ordnungsgemäß zu funktionieren.

Es ist wichtig, solche Abhängigkeiten effektiv zu verwalten, um zuverlässige und wartbare Unit-Tests zu schreiben (d. h. Tests, die langfristig, während der gesamten Entwicklung einer Codebasis, gültig, flexibel und nützlich bleiben).

Durch effektives Abhängigkeitsmanagement erstellen Tester eine robustere und zuverlässigere Testsuite, die das erwartete Verhalten aufweist. Entwickler verwenden die Abhängigkeitsinjektion, um abhängigkeitsbezogene Codezeilen in einen Code einzufügen (oder zu „injizieren“).

Anwendungsentwicklung

Steigen Sie ein: Entwicklung von Enterprise-Anwendungen in der Cloud

In diesem Video erläutert Dr. Peter Haumer, wie die moderne Entwicklung von Unternehmensanwendungen in der Hybrid Cloud heute aussieht, indem er verschiedene Komponenten und Praktiken demonstriert, darunter IBM Z Open Editor, IBM Wazi und Zowe. 

11 Best Practices für Komponententests

Jede hier beschriebene Teststrategie unterstützt Best Practices und spiegelt einen praxisorientierten Testansatz wider.

1. Mocks und Stubs nutzen

Testumgebungen sind auf die Verwendung von Mocks und Stubs angewiesen, um die für Tests erforderliche umfassende Isolierung zu gewährleisten.

Mock-Objekte sind quasi Duplikate, die Testern dabei helfen, das wahrscheinliche Verhalten tatsächlicher Objekte zu bewerten, indem sie simulierte Objekte vollständig isolieren.

Stubs liefern Analysten Daten über wahrscheinliche Interaktionen mit externen Abhängigkeiten, wie Komponenten, Dateisystemen und Datenbanken.

2. Extreme Nutzungsmuster untersuchen

Die Fehlererkennung ist ein wesentlicher Bestandteil der Unit-Tests. Tester bewerten extreme Nutzungsmuster, die nahe den Betriebsparametern oder Grenzwerten eines Geräts auftreten. Diese werden als „Edge Cases” bezeichnet und sind möglicherweise nicht ohne Weiteres erkennbar, wie beispielsweise bei einem Array-Zugriff außerhalb des zulässigen Bereichs. In diesem Fall erkennt der Tester, dass der Index für die Artikel den maximal zulässigen Wert für diesen Index überschreitet.

In solchen Fällen ist der Tester häufig gezwungen, ein Refactoring des Codes durchzuführen, was bedeutet, dass der Code trotz seiner bestehenden Funktionalitäten neu strukturiert werden muss.

3. Verwendung von CI/CD-Pipelines

Continuous Integration/Continuous Delivery (CI/CD)-Pipelines sind für den Testprozess von entscheidender Bedeutung, da sie Testfunktionen automatisieren.

Durch das Ausführen von CI/CD-Pipelines können automatisierte Komponententests jederzeit stattfinden, wenn Codeänderungen vorgenommen werden. Automatisierte Tests können Fehler frühzeitig im Entwicklungsprozess erkennen und dienen der Sicherung der Codequalität.

4. Tests sollten kurz, einfach und schnell sein

Zahlreiche Faktoren beeinflussen die Wartbarkeit von Tests. Um als wartungsfähig zu gelten, muss Testcode eine optimale Lesbarkeit, durchgängige Klarheit und fundierte Identifizierungsmethoden aufweisen. Kurz gesagt, Tests sollten sich durch hochwertigen Produktionscode auszeichnen.

Sie sollten auch als kleine und fokussierte Tests geschrieben werden, die sich mit bestimmten Modulen befassen. Tests sollten auch im Hinblick auf die Geschwindigkeit erstellt werden, da schnellere Tests häufiger und in kürzerer Zeit durchgeführt werden können.

5. Seien Sie vorsichtig mit Namenskonventionen

Wenn Tester die richtigen Namenskonventionen nicht beachten, können ansonsten gute Tests leicht übersehen werden. Testnamen sollten prägnant sein, jedoch ausreichend Informationen enthalten, um das Thema vollständig zu beschreiben, damit sie bei Bedarf gefunden und abgerufen werden können. Die Bezeichnung eines Tests als „Test-1“ liefert nicht ausreichend Informationen darüber, was getestet wird und warum.

6. Erstellen Sie Tests für alle Eventualitäten

Der Aufbau einer robusten Codebasis erfordert Tests, die sich sowohl positive als auch negative Szenarien vorstellen. Für positive Szenarien müssen Tester Tests für gültige Eingaben hinzufügen. Bei negativen Szenarien müssen Tester mit unerwarteten oder ungültigen Eingaben rechnen.

Es ist ebenfalls wichtig, die Testabdeckung von Grenzfällen und Randbedingungen aufrechtzuerhalten, um sicherzustellen, dass Ihr Code flexibel genug ist, um alle Arten von Situationen zu bewältigen.

7. Folgen Sie dem AAA-Muster

Die Tests sollten den Standardtestmustern folgen, wie dem bewährten Muster Arrange-Act-Assert (AAA).

Nach dem AAA-Muster muss der Code in einem Unit-Test organisiert und vorbereitet werden, bevor die erforderlichen Schritte zur Durchführung des Tests durchgeführt werden. Abschließend werden die Testfälle bewertet, um festzustellen, ob sie die erwarteten Testergebnisse erzielt haben.

8. Ausführlich und regelmäßig testen

Wie viel Code ist testbar? Dieser Betrag hängt von den spezifischen Umständen Ihres Unternehmens ab. Wenn jedoch das Testen das Ziel ist, ist es gut, so hoch wie realistisch und machbar möglich zu zielen.

Tester sollten eine Testabdeckung im Bereich von 70–80 % anstreben und eine regelmäßige Häufigkeit der Tests sicherstellen.

9. Wiederherstellen der Testumgebung

Die Tests sollten in einer sauberen Testumgebung durchgeführt werden. Das bedeutet, dass Tester die Demontageverfahren befolgen sollten, die sich auf die Wiederherstellung eines Systems nach Abschluss der Tests beziehen.

Typische Teardown-Aktionen können erfordern, dass Tester temporäre Dateien löschen, globale Variablen ändern oder Datenbankverbindungen schließen. Andernfalls kann es leicht zu Testfehlern kommen, da vorhandene Teile von Streucode zukünftige Tests beeinträchtigen.

10. Die öffentliche Schnittstelle nicht vergessen

Berücksichtigen Sie bei der Planung von Unit-Tests die Art der Verwendung Ihres Codes. Die öffentliche Schnittstelle muss ebenso getestet werden wie alle öffentlichen Eigenschaften oder Methoden innerhalb des Codes.

Um den Fokus beizubehalten, ist es besser, die Testimplementierung auf diejenigen Details zu beschränken, die Teil der öffentlichen Anwendungsprogrammierschnittstelle (API) sind.

11. Tests auf Code-Funktionalität ausrichten

Es besteht ein deutlicher Unterschied zwischen der Funktionalität des zu testenden Codes und den zugrunde liegenden Business Rules, die für dieses System gelten könnten. Die durchgeführten Tests sollten ausschließlich die Funktionalität des Codes bewerten.

Tools für Unit-Tests

Entwicklern stehen verschiedene Tools für Komponententests zur Verfügung. Hier sind die am häufigsten verwendeten:

  • Jest: Das Framework von Jest ist sowohl bei erfahrenen Entwicklern als auch bei Neulingen (die seine Benutzerfreundlichkeit schätzen) sehr beliebt und analysiert React- und JavaScript-Komponenten. Ziel ist es, eine Testumgebung ohne Konfiguration mit minimalem Einrichtungsaufwand und schneller Testerstellung bereitzustellen. Ein weiterer Pluspunkt ist die Art und Weise, wie Jest die Testabdeckung meldet und die Gesamtmenge des zu validierenden Codes bewertet.
  • JUnit: Wenn Java™ Komponenten evaluiert werden müssen, wählen Tester normalerweise JUnit. JUnit bietet eine optimale Code-Unternehmen, eine vielseitigere Code-Reparatur und eine bessere Erkennung. Für Kombinationen, die Vielseitigkeit schätzen, bietet JUnit die passende Lösung. Sie rationalisiert nicht nur den Testprozess, sondern kann auch während des Integration Testing und Functional Testing des gesamten Systems verwendet werden.
  • Pytest: Pytest verwaltet auf einfache Weise das Schreiben und Ausführen von Tests, die auf der Programmiersprache Python basieren. Pytest kann auch für Unit-Tests, Integration Testing, Functional Testing und End-to-End-Tests eingesetzt werden. Es ist bekannt für seine integrierte Unterstützung der Testparametrisierung, sodass Sie denselben Test mit unterschiedlichen Variablen ausführen können, ohne dass es zu einer Duplizierung des Codes kommt.
  • xUnit: C#-Entwickler verwenden in der Regel das beliebte Open-Source-Unit-Testing-Framework xUnit. Sie schätzen die Testumgebung als ideal für die tiefe Isolierung, die für das Testen von Komponenten erforderlich ist. Sie lässt sich sogar gut mit anderen Testtools kombinieren und trägt so zu einem reibungslosen Workflow bei. Die Syntax von xUnit trägt zur Vereinfachung der Testerstellung bei.

Wie sich KI auf Komponententests auswirkt

Es ist mittlerweile allgemein bekannt, dass sich die gesamte Computerbranche derzeit in einem Umbruch befindet und durch die Rechenleistung der künstlichen Intelligenz (KI) revolutioniert wird. Komponententests erzielen aufgrund der KI ihre eigenen Vorteile:

  • Umfassende Testabdeckung: Der wichtigste Aspekt von Unit-Tests ist die Fehlererkennung. KI kann Fehler finden, die menschlichen Testern möglicherweise entgehen. Zusätzlich kann KI „selbstheilende“ Tests erstellen, die im Laufe der Zeit dazulernen. Das ist eine wichtige Entwicklung.
  • Rasches Schreiben von Tests: Tester gehen bei Produktionsumgebungen von Situationen aus, die oft fließend sind und deren Anforderungen sich schnell ändern können. Glücklicherweise kann KI komplizierte Dinge schnell ausführen, wie z. B. die Entwicklung ganzer Suite von Komponententests, um die Entwicklungsteams im Zeitplan zu halten.
  • Ständiges Feedback: Einer der Vorteile der KI-Nutzung ist die Art und Weise, wie sie die Nutzung von Entwicklungsumgebungen ausgleicht und verbessert, ganz zu schweigen von DevOps und CI/CD-Pipelines. Der unmittelbare Vorteil für Tester ist das kontinuierliche Feedback, das sie erhalten, was wiederum schnellere Entwicklungszyklen ermöglicht.
  • Spezialisierte Testanalyse: Mit KI haben Tester wesentlich mehr Spielraum hinsichtlich der Art der Tests, die sie durchführen können. KI kann beispielsweise eine Ursachenanalyse durchführen, um die Ursachen für Testfehler zu ermitteln. Außerdem kann sie komplexere Tests durchführen, wie beispielsweise eine prädiktive Testfehleranalyse, bei der anhand von Codemustern und historischen Daten zukünftige Testfehler prognostiziert werden.
Weiterführende Lösungen
IBM Enterprise Application Service für Java

Ein vollständig verwalteter, mandantenfähiger Service für die Entwicklung und Bereitstellung von Java-Anwendungen.

Java-Apps erkunden
DevOps-Lösungen

Verwenden Sie DevOps-Software und -Tools, um cloudnative Anwendungen für mehrere Geräte und Umgebungen zu erstellen, bereitzustellen und zu verwalten.

DevOps-Lösungen erkunden
Services für die Entwicklung von Unternehmensanwendungen

Die Entwicklung von Cloud-Anwendungen bedeutet: einmal erstellen, schnell iterieren und überall bereitstellen.

Services für die Anwendungsentwicklung
Machen Sie den nächsten Schritt

IBM Cloud Application Development Consulting Services bieten fachkundige Beratung und innovative Lösungen zur Optimierung Ihrer Cloud-Strategie. Arbeiten Sie mit den Cloud- und Entwicklungsexperten von IBM zusammen, um Ihre Anwendungen zu modernisieren, skalieren und beschleunigen und so transformative Ergebnisse für Ihr Unternehmen zu erzielen.

Mehr zu Services zur Anwendungsentwicklung Erste kostenlose Schritte beim Erstellen auf IBM Cloud