Aus der Werkzeugkiste, Teil 1: Philip Ackermann
Seite 2: Integration Testing bis CI
6. Integration Testing
"Beim Thema Integration Testing steht in unserem Team nach wie vor das Selenium-Framework an erster Stelle, genauer gesagt Selenium 2.0, das im Unterschied zur ersten Version des Frameworks auch die sogenannte Web Driver API implementiert.
Mit Hilfe des Node.js-Modules webdriverio können wir Selenium 2.0 sogar unter Node.js nutzen. In Kombination mit dem Node.js-Module webdrivercss lassen sich zudem relativ einfach und automatisch visuelle Regressionstests durchführen, bei denen Entwickler zwei Snapshots einer Webseite auf ungewollte, durch Änderungen am CSS ausgelöste Layout-Abweichungen untersuchen können.
Auf meiner Liste der "Frameworks, die ich mir angucken möchte" steht gerade außerdem Nightwatch.js. Es ist ebenfalls für Integrationstests interessant und nutzt auch Selenium 2.0 als Basis.
Ansonsten habe ich derartige Regressions- und Integrationstests aber auch schon direkt mit PhantomJS geschrieben. Das ist zwar oft mĂĽhsamer, funktioniert aber fĂĽr einfache Tests. FĂĽr das PrĂĽfen von AngularJS-Anwendung bietet sich dagegen das projekteigene Protractor an."
7. Code Coverage
"Bezüglich der Testabdeckung habe ich anfangs relativ viel herumprobiert und unterschiedliche Bibliotheken getestet. Letztlich bin ich bei Blanket.js hängengeblieben, weil es sich vergleichsweise unkompliziert und ohne viel Konfigurationsaufwand in Testframeworks wie QUnit, Jasmine und Mocha integrieren lässt.
Um Blanket.js mit QUnit verwenden zu können, muss man lediglich die entsprechende Quelltextdatei von der Blanket.js-Webseite herunterladen und in den QUnit-Testrunner einbinden. Möchte man Blanket.js in Kombination mit Mocha einsetzen, lässt es sich über npm innerhalb des entsprechenden Projekts installieren (npm install blanket). Anschließend kann es über require('blanket')() in den jeweiligen Test eingebunden und direkt aufgerufen werden. Darüber hinaus lässt sich Blanket.js über entsprechende Plug-ins ebenfalls in die Build-Tools Grunt (z.B. über grunt-blanket) und Gulp (z.B. über gulp-blanket-mocha) integrieren.
Im Team dagegen verwenden wir fĂĽr die Testabdeckung mittlerweile das Tool Istanbul, das sich dank Clover-konformen Reports nahtlos in unseren CI-Server einfĂĽgt."
8. Building
"Für das Building verwendet unser Team in schätzungsweise 80 Prozent der JavaScript-Projekte Grunt und für die restlichen 20 Gulp. Bezüglich der Definition und Konfiguration von Tasks verfolgt Grunt ja bekanntermaßen den "Configuration over Code"-Ansatz, neigt aber dadurch auch zu aufgeblähten, sehr langen Konfigurationen. Gulp hingegen ist durch seinen "Code over Configuration"-Ansatz leserlicher.
Für neue Projekte verwenden wir daher meist Gulp und haben das mittelfristige Ziel, auch die "alten" Grunt-Projekte entsprechend anzupassen. Allerdings hat das eine vergleichbar geringe Priorität, zumal wir auch bei den Grunt-Konfigurationen immer darauf geachtet haben, dass sie nicht ausarten.
Nicht empfehlen kann ich ĂĽbrigens, JavaScript-Projekte mit Ant oder Maven zu bauen. Die entsprechenden Plug-ins, die ich mir vor einigen Jahren diesbezĂĽglich einmal angeschaut hatte, waren alles andere als einfach zu konfigurieren. Es kann zwar sein, dass sich da in den letzten Jahren etwas verbessert hat, aber ich wĂĽrde in Projekten, in denen sowohl Java- als auch JavaScript-Komponenten zu entwickeln sind, das Building dementsprechend aufteilen, also Java-Komponenten mit Ant oder Maven und JavaScript-Komponenten mit Gulp oder Grunt bauen."
9. Deployment
"Für das Deployment kommen bei uns meistens individuelle Grunt- oder Gulp-Skripte zum Einsatz. Mit ihrer Hilfe lassen sich dann zum Beispiel Sass-Daten in CSS umwandeln, HTML,- CSS- und JavaScript-Dateien minifizieren, JavaScript-Code, der in ES6/ES2015 geschrieben ist, bei Bedarf in ES5-kompatiblen Code umwandeln, Bilddateien komprimieren oder in unterschiedlichen Auflösungen generieren und vieles andere mehr. Auf die Uglifier-Funktionen von Tools wie YUI Compressor, UglifyJS2 oder Google Closure Compiler, die beispielsweise Variablennamen ersetzen, verzichten wir dagegen.
Außerdem achten wir bei Node.js-Modulen stark darauf, dass sich jedes Modul über npm install vollständig installieren lässt. Das funktioniert mittlerweile dank entsprechender npm-Updates auch für Abhängigkeiten, die auf privaten Git-Servern liegen. Auf die Weise können wir auch interne Bibliotheken und Ähnliches vollständig mit npm verwalten und müssen nicht mit eigenen Skripten nachhelfen. Und ja: Docker steht ebenfalls auf der Liste der coolen neuen Techniken, die ich mir in dem Zusammenhang noch angucken möchte."
10. Continuous Integration
"FĂĽr Continuous Integration verwenden wir im Team den aus dem Java-Umfeld bekannten CI-Server Jenkins. Ein in dem Zusammenhang besonders nĂĽtzliches Tool ist, wie ich finde, das Grunt-Plug-in grunt-jenkins. Mit ihm lassen sich Jenkins-Jobs in Form von XML-Konfigurationsdateien vom Jenkins-Server herunterladen, lokal aktualisieren und anschlieĂźend wieder auf den Jenkins-Server hochladen. Insbesondere wenn man es mit vielen Jenkins-Jobs zu tun hat, erleichtert das die Verwaltung erheblich.
Für alle unsere Projekte haben wir spezielle Grunt- oder Gulp-Tasks, die das System auf dem Jenkins-Server anstößt, um Unit-Tests auszuführen, die Testabdeckung zu ermitteln, den Code-Style zu überprüfen und/oder Distributionen zu erzeugen.
Externe Jenkins-Plug-ins, die in dem Zusammenhang beispielsweise zum Einsatz kommen, sind das NodeJS-Plug-in für die Integration von Node.js, das Checkstyle-Plug-in für die Code-Analyse über Checkstyle, das Clover-Plug-in für das Erzeugen von Code-Coverage-Reports via Clover, das GitHub-Plug-in für das Verbinden zu GitHub und das Bulk-Builder-Plug-in für das einfache Konfigurieren zusammengehöriger Builds."
Letzter Tipp
"Bei all den vielen Bibliotheken, Frameworks und Tools, die es gerade im Bereich der JavaScript-Entwicklung gibt, sollte man sich von der Fülle nicht allzu sehr ablenken lassen. Ich finde es wichtiger und für den Programmieralltag effektiver, einige wenige Frameworks richtig zu beherrschen, statt sich alle paar Tage auf ein neues zu stürzen. Die JavaScript-Community macht es einem da sicherlich nicht leicht, mit all den Dingen, die täglich per Twitter und auf anderen Kanälen teils ungefiltert auf einen einwirken: neues Framework hier, neues Tool da. Und alle machen es besser als die bisherigen.
Klar sollte man hier und da über den Tellerrand schauen, bestehende Frameworks hinterfragen und neuen Tools eine Chance geben. Aber hier gilt meiner Meinung: nicht zu viel Zeit damit verbringen und sich wie gesagt nicht verwirren lassen. Unterm Strich zählt es doch, möglichst effektiv Anwendungen zu entwickeln. Ob ich das dann mit AngularJS oder mit React mache, ist eine Art Glaubensfrage und eine Sache des persönlichen Geschmacks."
Philip Ackermann
entwickelt seit 15 Jahren Web- und Softwareanwendungen, arbeitet beim Fraunhofer-Institut für Angewandte Informationstechnologie FIT im Bereich Web Compliance und eHealth und ist Autor zweier Fachbücher über Java und JavaScript sowie mehrerer Fachartikel. Sein nächstes Buch erscheint im Sommer 2016.
(jul)