Wer das Wort Unit Test zum aller ersten Mal hört und dabei denkt, dass man irgendwelche Units (also Einheiten) von beispielsweise League of Legends auf ihre Kampfestüchtigkeit, Effekte etc. hin prüfen will, wird hier leider enttäuscht werden. Tatsächlich verbirgt sich hinter diesem Begriff das Testen einzelner Komponenten eines Systems auf seine isolierte Tüchtigkeit. Auch wenn es weitere Arten von Tests, wie Integrationstests, Systemtests oder Akzeptanztests gibt, wollen wir uns lediglich auf die Unit-Tests schwerpunktmäßig konzentrieren. Damit Unit, Marsch!
Unit Tests: Grundlagen und Best Practices für Qualitätssicherung
Inhaltsverzeichnis
Welche Testarten gibt es?
Wie schon aus dem Intro angeklungen, gibt es eine Reihe an diversen Testarten, die für ein System gelten, diese wären laut Testpyramide hierarchisch gesehen:
Wie man sieht, befinden sich auf der untersten Ebene die Unit-Tests, gefolgt von Integrations-Tests, System-Tests und Akzeptanz-Tests, die sich folgendermaßen unterscheiden:
Unit-Test: Testfälle, die jede einzelne Komponente eines Systems isoliert testen. Was die Geschwindigkeit angeht, sind diese Art von Tests performant die schnellsten.
Integrations-Test: Testfälle, bei denen das Zusammenspiel von mindestens zwei Komponenten getestet wird. Da hier mehr als eine Komponente getestet wird, ist die Performance entsprechend langsamer.
System-Test: Testfälle, die den gesamten Workflow eines Systems testen, sprich End-to-End-Tests. Die Frage, die man sich hier stellen sollte, ist “Funktioniert alles wie spezifiziert?“. Diese Testfälle gehören neben den Akzeptanztests zu den performant anspruchsvollsten.
Akzeptanz-Test: Bei dieser Testart, wird nun vom Kunden selber getestet, ob die eigenen Erwartungen erfüllt wurden. Darunter können rechtliche Anforderungen oder die Benutzerfreundlichkeit fallen. Die Frage, die man sich hier stellen sollte, ist “Ist das, was geliefert wurde, das, was ich als Kunde brauche?“
Warum sind Unit-Tests wichtig?
Als eine der fundamentalsten Testarten sind Unit-Tests aus folgenden Gründen wichtig:
Da dabei jede einzelne Komponente isoliert getestet wird, können auf diese Weise Bugs vorzeitig entdeckt werden, bevor sie sich auf andere Teile des Systems auswirken
Da Unit-Tests klein und übersichtlich sind, lässt sich ein Refactoring schneller durchführen
Ist ein Unit-Test gut dokumentiert, kann die Funktionsweise dieser Komponente einfach nachvollzogen werden
Mit Unit-Tests werden insbesondere Ressourcen und Zeit gespart, da diese Komponenten nicht mehr manuell getestet werden müssen
Was sind die Grundprinzipien bzw. Best Practices von Unit-Tests?
Wichtig ist, dass Unit-Tests nur eine Funktion oder Methode ohne externe Abhängigkeiten prüft
Speeeeed: Egal wann und wie oft sie ausgeführt werden, sollten Unit-Tests innerhalb von Millisekunden laufen und das ohne abweichende Ergebnisse
Unit-Tests sollten das AAA-Prinzip befolgen:
Arrange: Vorbereiten von Testdaten und Umgebung
Act: Aufrufen der Methode
Assert: Überprüfung vom Ergebnis
Jeder Unit-Test sollte nur ein Szenario überprüfen
Was häufig missachtet wird, ist, dass man sich an keine einheitliche Namenskonvention hält, wo klar gemacht wird, was die Funktion und Ziel vom aktuellen Testfall sein soll
Unter keinen Umständen sollte eine neue “Produktionslogik“ in die Unit-Tests eingebaut werden, denn das Ziel ist letztendlich die Verifikation vorhandener Funktionen
Unit-Tests sollten regelmäßig ausgeführt werden, um etwaige Regressionen schnell und frühzeitig zu erkennen
Welche Tools und Frameworks gibt es für Unit-Tests?
Hier muss man bedenken, dass es für viele Programmiersprachen eigene Unit-Test Tools sowie Frameworks gibt. Da gibt es folgende zur Auswahl:
Java
JUnit: Das Standard-Tool für Unit-Tests
TestNG: Die fortgeschrittenere Version von JUnit, die zusätzliche Funktionen wie unter anderem parallele Testausführung und datengetriebenes Testen mitbringt
Mockito: Ein Framework für Mocking und Stubbing von Abhängigkeiten
AssertJ: Ist eine Bibliothek für fließende und ausdrucksstarke Assertions für JUnit Tests
Python
unittest: Eingebautes Standardmodul für Unit-Tests
pytest: Ist ein erweitertes Framework zu unittest, das einfacher zu bedienen ist und zusätzlich mehr Funktionen mitbringt
mock: Ein Framework für das Mocking von Abhängigkeiten
hypothesis: Ist eine Python-Bibliothek für Property-based Testing
JavaScript/TypeScript
Jest: Ein All-in-One-Framework für Unit-Tests, Integrationstests und Snapshot-Tests
Mocha: Ein Test-Runner, der synchronen und asynchronen Code testen kann
Chai: Eine auf BDD/TDD basierte Assertion Library
Sinon: Ein Framework für Mocking, Spies und Stubs
C#/.NET
MSTest: Ist ein Unit-Test-Framework für .NET aus dem Hause Microsoft
xUnit.net: Ein moderneres und performanteres Unit-Test Framework, das für neuere .NET-Projekte gedacht ist
NUnit: Ein Unit-Test Framework, das für Nutzer gedacht ist, die eher ein Freund von JUnit ähnlichen Strukturen sind
Moq: Ein Framework für Mocking
Fazit zu Unit-Tests
Der erste Schritt ins “professionelle Business” des Testens zu gehen, besteht darin, zunächst vom Kleinen aus zu beginnen, sprich jede Komponente eines Systems sollte zunächst durch einen Unit-Test abgedeckt sein, ehe man auf die höheren Ebenen der Testpyramide geht. Dadurch wird sichergestellt, dass auch jede einzelne Komponente tatsächlich frei von Fehlern ist. Sollten dabei nämlich Fehler auftreten, während die Unit-Tests grün durchlaufen, bedeutet das, dass die Komponenten funktionsfähig sind und das Problem an anderer Stelle zu suchen ist, was in der Regel dann in weiteren Schritten mit Integrationstests etc. weiter eingegrenzt werden kann. Unit-Tests eliminieren daher präventiv Fehlerherde auf der untersten Ebene, ehe sie auf die höheren Ebenen schwappen können. Das Gute ist, dass man sich nicht auf eine spezielle Programmiersprache spezialisieren muss, um solche Tests einzupflegen, da es für viele Programmiersprachen diverse Tools und Frameworks gibt, mit denen man direkt mit dem Testen loslegen kann.
FAQ - Unit-Tests
Q: Warum sind Unit-Tests wichtig?
Sie helfen, Fehler frühzeitig zu erkennen, verbessern die Code-Qualität und erleichtern spätere Änderungen oder Refactorings.
Q: Was ist der Unterschied zwischen Unit-Tests und Integrationstests?
Unit-Tests prüfen einzelne Code-Einheiten isoliert, während Integrationstests das Zusammenspiel mehrerer Komponenten testen.
Q: Wie viele Unit-Tests sollte man schreiben?
Das hängt vom Projekt ab, aber eine hohe Code-Abdeckung von z. B. 80 % ist ein guter Richtwert.
Q: Verlangsamt das Schreiben vieler Unit-Tests die Entwicklung?
Kurzfristig ja, langfristig sparen man jedoch Zeit durch weniger Fehler und stabileren Code.
Q: Wie kann man sicherstellen, dass Unit-Tests zuverlässig sind?
Tests sollten deterministisch sein, d. h. sie liefern immer das gleiche Ergebnis bei gleichen Eingaben.
Q: Wann sollten Unit-Tests ausgeführt werden?
Automatisiert bei jedem Commit oder in der CI/CD-Pipeline, um eine kontinuierliche Qualitätssicherung zu gewährleisten.
Professionelles Testmanagement
Sie möchten Ihre Testprozesse strukturieren und optimieren? Unsere Testmanagement-Experten unterstützen Sie bei Teststrategie, Tool-Auswahl und Prozessverbesserung.
Testmanagement anfragen