Entdecke die Möglichkeiten!

JavaScript Testing im Aufwind (Teil 4)
Kommentare

Windows Developer

Der Artikel „JavaScript Testing im Aufwind“ von Sebastian Springer ist erstmalig erschienen im Windows Developer 7.2012
Was macht einen guten Test aus?
Für die Erstellung von Unit

Windows Developer

Der Artikel „JavaScript Testing im Aufwind“ von Sebastian Springer ist erstmalig erschienen im Windows Developer 7.2012

Was macht einen guten Test aus?

Für die Erstellung von Unit Tests existieren einige Best Practices, auf die hier kurz eingegangen werden soll. Der wichtigste Punkt steckt bereits im Namen „Unit Test“. Durch einen Unit Test wird eine Softwareeinheit geprüft. Damit dies funktioniert, muss diese Einheit so unabhängig wie möglich vom Rest der Applikation sein.

Ein Test darf außerdem keine weiteren Tests beeinflussen. Tests sollten auch nicht aufeinander aufbauen. Werden sie verkettet, gestaltet sich die Fehlersuche schwierig und aufwändig, da die negativen Auswirkungen eines Tests auf die nachfolgenden kaum absehbar sind. In einem Test sollten so wenige Assertions wie möglich und so viele wie nötig eingesetzt werden.

Ein Test darf nur genau einen Sachverhalt abtesten, sodass ein fehlschlagender Test auf genau ein Problem an einer bestimmten Stelle hinweist. Ein weit verbreitetes Antipattern ist es, verschiedene Eigenschaften in einem Test abzudecken, nur weil es sich gerade anbietet und die notwendige Testumgebung für diesen Test ohnehin schon aufgesetzt ist.

Das Problem, das hierdurch entsteht, ist, dass ein fehlschlagender Test dann wieder verschiedene Ursachen haben kann und nicht mehr eindeutig auf ein Problem hinweist. Tests dürfen keinen Nutzereingriff erfordern. Ziel ist es, sie automatisiert in möglichst hoher Frequenz, idealerweise bei jedem Commit ins Versionskontrollsystem, auszuführen.

Sie müssen so wenig Aufwand für den Entwickler wie möglich erzeugen – ansonsten werden sie früher oder später nicht weiterentwickelt; sie veralten und werden schließlich komplett eingestellt. Tests bieten eine Möglichkeit, die Funktionsweise von Softwareeinheiten zu dokumentieren. Durchdachte Tests bieten Entwicklern, die nicht unmittelbar an der Erstellung des getesteten Quellcodes beteiligt waren, die Möglichkeit, dessen Funktionsweise im konkreten und isolierten Anwendungsfall zu sehen.

Pro Softwareeinheit existiert nicht nur ein Test, sondern eine Reihe davon, mindestens jedoch zwei. Ein Test prüft den erfolgreichen Ablauf der Routine. Ein weiterer prüft den Fehlerfall. Je nach Komplexität des Quellcodes sind weitere Tests notwendig, welche die verschiedenen Erfolgs- oder Fehlerfälle prüfen.

Existieren für eine Routine Grenzfälle wie bspw. der Übergang vom negativen in den positiven Zahlenraum, müssen diese ebenfalls getestet werden – was den Vorteil hat, dass das Verhalten im Grenzbereich dokumentiert und getestet ist.

Testsuite selber bauen

Neben der Codeorganisation ist es in vielen Unit-Test-Frameworks möglich, einzelne Tests in so genannten „Testsuiten“ zu gruppieren. Damit wird ein Verbund erzeugt, der in seiner Gesamtheit getestet werden soll. In QUnit bietet die Methode module() die Möglichkeit, Tests logisch zu gruppieren und sie so zu organisieren. Innerhalb der Methode module() können neben dem Namen der Testsuite zusätzlich zwei weitere Callback-Funktionen definiert werden, die jeweils vor bzw. nach den einzelnen Testfällen ausgeführt werden.

Dieses Feature wird vor allem dazu genutzt, ein bestimmtes Szenario herzustellen, innerhalb dessen der Test später ablaufen soll, und um bestimmte Aufräumprozeduren nach Ablauf des Tests auszuführen. Vorteilhaft ist diese Gruppierung in Module auch deshalb, weil einzelne Gruppen dadurch gezielt ausgeführt werden können. Wird der Name des Moduls an den URL der Tests angehängt, wird nur dieses eine Modul ausgeführt, z. B. http://www.myQunittest.html?MathOperations.

Problemquelle Server

In den seltensten Fällen stehen JavaScript-Applikationen alleine für sich. Die Daten, die während der Laufzeit entstehen, werden zur Weiterverarbeitung und Wiederverwendung an einen Server geschickt bzw. von dort ausgelesen. Diese Schnittstelle stellt ein Problem für Unit Tests dar:

Wird eine Funktionalität, die auf einer asynchronen Anfrage zum Server basiert, mit einem Test abgesichert, müsste diese theoretisch mit abgetestet werden. Um das zu bewerkstelligen muss dann allerdings ein entsprechender Server für die Testumgebung existieren und für jeden Testlauf zur Verfügung stehen. Treten während der Ausführung der Tests Probleme in der Infrastruktur auf, so schlägt der Test fehl, obwohl die ursprünglich zu testende Einheit einwandfrei funktioniert.

Asynchrones Testen done right

Die Lösung dieses Problems liegt in der Verwendung von Mock-Objekten für asynchrone Anfragen. In den meisten Unit-Test-Frameworks ist eine solche Funktionalität bereits integriert und kann ohne Weiteres verwendet werden.

Ein weiterer Vorteil ist, dass die asynchronen Unit Tests durch die wegfallenden Wartezeiten auf die Antwort des Servers um einiges performanter werden, was die Akzeptanz unter Entwicklern erhöht.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -