Artikelformat

GWT-Unittests mal anders

Bei diesem Thema geht es nicht um PHP, sondern um das Google Web Toolkit. Seit ein paar Monaten befasse ich mich mit diesem Toolkit und war bisher immer von den Unittests genervt, da diese sehr viel Zeit für die Durchführung und noch mehr im Fehlerfall benötigen. Die Unittests können mit einer kleinen Bibliothek beschleunigt werden.

Unittest in GWT werden immer mit Hilfe eines Tomcat-Servers ausgeführt. Dadurch sind solche Tests relativ langsam. Auf meinem System dauert ein durchschnittlicher Unittest ca 40-60 Sekunden. Unser CI-System ist etwas schneller, aber auch nicht wesentlich. Richtig lang dauert es, wenn ein Unittest fehl schlägt. GWT versucht diesen dann 3 mal zu wiederholen und wartet zwischen den Wiederholungen noch auf einen Timeout, der üblicherweise bei 300 Sekunden liegt. Bei der ausgiebigen Nutzung von Unittests konnten wir manche Komponente unseres Systems dazu bringen fast 1h für Unittests zu vergeuden. Dadurch wird ein CI-System mehr oder weniger lahm gelegt und Aktualität ist auch etwas anderes.

Auf der Suche nach einer Lösung für dieses Problem wurden verschiedene Standardverfahren angewendet. Unittests in einer Suite zusammenfassen, da der Tomcat weniger oft hoch bzw. runtergefahren werden muss; Die Wiederholungen auf 1 setzen; MVP einführen, um GWT Unittests durch herkömmliche jUnit-Tests zu ersetzen. Der große Zeitgewinn konnte bis dahin aber nicht erzielt werden.

Den Durchbruch hat die gwt-test-utils Biliothek gebracht. Diese ersetzt grob gesagt einfach die GWT-Unittests durch eigene. Da hierfür kein Tomcat mehr benötigt wird spart man sehr viel Zeit. Und weil weiter die GWT-Timeouts nicht mehr existieren spart man noch sehr viel mehr Zeit.

Um einen gwt-test-utils Unittest zu nutzen benötigt man neben den üblichen Bibliotheken (wie junit4, gwt-user und gwt-servlet) die gwt-test-utils Bibliothek. Diese hat Abhängigkeiten zu javassist, log4j und easymock. Den Unittest leitet man nun nicht von GWTTestCase sondern von AbstractGwtTest ab und passt möglicherweise noch die Asserts an. Wenn man keine asynchronen Tests schreibt ist man somit eigentlich schon fertig.

Gwt-Test-Utils funktioniert nun so, dass der Java-Classloader so modifiziert wird, dass beim Laden einer Klasse, diese gepatcht wird. Das bedeutet, wenn in einer GWT-Klasse Javascript Code vorhanden ist, wird dieser durch ein Java-Derivat ersetzt. Dieser Code ist die Ursache, wieso man keine normalen junit Test nutzen kann. Und daher wird der Code ersetzt. gwt-test-utils hat sehr viele der GWT Klasse so gepatcht, bzw stellt Patcher-Klassen bereit. Wenn eine Komponente von GWT nicht aussreichend durch Patches abgedeckt ist, so kann man dies durchaus selbst ergänzen, da die Bibliothek OpenSource ist und es sowieso ratsam ist den Trunk zu beutzen, oder man schreibt ein Issue an die Entwickler. Diese werden erfahrungsgemäß relativ zeitlich bearbeitet.

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.