Testing Testing
Ran an die Tests!

Freitag, 01. Dezember 2017

Schon ewig geplant, aber lange schmählich vernachlässigt, habe ich bei ModuleStudio die automatisierten Tests. Zwar ist schon seit Längerem die Infrastruktur dahingehend ausgerichtet, was beispielsweise die Git-Struktur und die Jenkins-Pipelines anbelangt, allerdings bringt das relativ wenig, wenn es fast nur Dummy-Tests ohne jeglichen Inhalt gibt.

Da ModuleStudio 1.1.0 kürzlich veröffentlicht wurde, konnten danach in der Entwicklungsversion 1.2.0 einige Altlasten entfernt werden. Da hat es sich im Hinblick auf Timing und Ausgangslage angeboten, endlich zu starten.

Vorarbeiten und Werkzeuge

Wichtig war vor allem, die Tests wartbar zu halten. Denn wenn es erst einmal Tausende von Tests gibt, möchte man diese nicht andauernd anpassen müssen. Am Anfang stand daher erst einmal eine Evaluierung der einzelnen Tools und die damit einhergehende Einarbeitung in die Werkzeugkette. Zum Glück habe ich das schon in den letzten Jahren permanent gemacht und die Entwicklungen stets verfolgt, so dass bereits eine Vorauswahl zur Verfügung stand beziehungsweise klar war, welche Tools für ModuleStudio nicht relevant sind.

Nach aktuellem Stand werden die folgenden Werkzeuge eingesetzt:

  • Die Basis für Unittests bildet natürlich JUnit. Hier ist kürzlich die Version 5 erschienen, welche auch mit Eclipse verwendet werden kann.
  • Wie üblich verwenden wir zur Implementierung die Sprache Xtend, welche zu Java-Quellcode kompiliert. Die zahlreichen Fähigkeiten von Xtend, wie etwa Extension-Methoden, sorgen auch bei Unittests für prägnanten Code. Sofern nötig, können wir auf zusätzliche testspezifische Erweiterungen wie XFactory und JMockit-Xtend (eine Xtend-Integration des populären Mocking-Frameworks JMockit) zurückgreifen.
  • Zum Testen der DSL von ModuleStudio benutzen wir Xpect. Damit lassen sich Unit- und Integrationstests anhand von Beispielmodellen beschreiben, was gleichzeitig der Kommunikation und Verbesserung der Modellierungssprache dient. Die Beispielmodelle werden so zu ausführbaren Tests, was Regressionsfehler verhindert und die Testdaten von der Testimplementierung trennt. Die Beispiele werden außerdem stets aktuell und konsistent mit der Implementierung gehalten.
  • Für funktionale Tests bzw. UI-Tests gibt es eine ganze Menge unterschiedlicher Frameworks im Eclipse-Ökosystem. Nach eingehender Untersuchung haben wir uns für die die Verwendung von RCPTT entschieden.
  • Zur Messung der Testabdeckung (Code Coverage) wird EclEmma auf Basis von JaCoCo eingesetzt.
  • Zur Ausführung der Tests in den Maven-Builds kommt Tycho Surefire zum Einsatz.

Ein Plan zur Priorisierung

Da ModuleStudio mehrere Komponenten beinhaltet, bedarf es einer Reihenfolge, in der Testfälle für diese Komponenten hinterlegt werden sollen. Wir haben entschieden, uns hier von innen nach außen zu arbeiten, da in den inneren Teilen seltener Änderungen erforderlich sind.

  1. Zu Beginn werden die UI-unabhängigen Teile der DSL fokussiert. Das beinhaltet zum Beispiel den Parser zum Einlesen und Interpretieren der Modelldateien, die Validierungsregeln, den Formatierer, den Linker, Veränderungen am Syntaxbaum von Modellen, den Serialisierer, das sogenannte Scoping, und weitere Dinge. Während der Realisierung der ersten Testfälle konnten übrigens direkt ein paar kleinere Unstimmigkeiten in der Validierung und beim Formatieren entdeckt und behoben werden - da sieht man, wie wertvoll das automatische Testen ist!
  2. Anschließend geht es an die UI-bezogenen Teile der DSL. Hierzu zählen vor allem Funktionen des textuellen Editors, wie Content Assist, die Outline View, Code Templates oder Hovering. Aber auch andere, eher allgemeine Features sind wir angesiedelt, zum Beispiel die Workbench-Integration und Quick Fixes für Validierungsprobleme.
  3. Die Hilfe-Komponente bedarf nicht vieler Tests, da sie fast komplett von Eclipse stammt. Allerdings sollte die automatisierte Erstellung der Dokumentation (für die Hilfe, für die Website und als PDF-Datei) getestet werden, sofern möglich.
  4. Bei den Tests für den Generator muß abgewogen werden, wie weit man ins Detail gehen sollte, zumal sich Teile der Generator-Templates vergleichsweise häufig ändern. Es existiert bereits ein Beispieltest, der ein Modell generiert und prüft, ob bestimmte Dateien in der Ausgabe existieren. Darauf können wir später aufbauen.
  5. Als eigener Themenbereich sind die funktionalen Tests der UI von ModuleStudio anzusehen. Hier geht es um die Integration der Editoren, der Views und weitere Toolingbereiche wie Dialoge und Assistenten.

Der Fortschritt an den Arbeiten rund und für die Tests kann übrigens in diesem Ticket verfolgt werden.

Was ist mit den Anwendungen?

Komplett außen vor gelassen sind bislang Tests für die generierten Anwendungen. Dies ist ein eigenes Thema für sich, das hinterher gesondert behandelt wird, zumal der Generator auch einige Unit Tests automatisch erstellen könnte. Hier kommen dann Werkzeuge wie PHPUnit oder die DomCrawler-Komponente von Symfony zum Einsatz. Auch JavaScript-Dateien wollen getestet werden und und und.

Aktuell konzentrieren wir uns erst einmal darauf, die Fabrik für die Anwendungen abzusichern. Anschließend kann die Fabrik dann auch Dinge fabrizieren, die andere fabrizierte Dinge absichern.

 
^