Gute Qualität in JavaScript mit Jenkins und PHPStorm/WebStorm

Qualitatives JavaScript
Kommentare

Professionelle Software kann nur entwickelt werden, wenn schon im Entstehungsprozess auf die Qualität des entwickelten Produkts geachtet wird. Auch JavaScript ist mittlerweile ein elementarer Bestandteil von Webapplikationen, wenn es um businesskritische Logik auf Clientseite geht. Aus diesem Grund wird es immer wichtiger, auch auf die Qualität im JavaScript-Quellcode zu achten. Im Folgenden werden eine Reihe von Werkzeugen vorgestellt, die einem Entwickler die Arbeit dabei erheblich erleichtern.

Mit der Qualitätssicherung ist es wie mit vielen anderen Themen: Um sie richtig durchführen zu können und den maximalen Nutzen daraus zu ziehen, muss man die Hintergründe verstehen. Wird Qualitätssicherung lediglich durchgeführt, „weil es die anderen ja auch machen“, wird sich mit hoher Wahrscheinlichkeit kein positiver Effekt einstellen, vielmehr wird die Qualitätssicherung den Entwicklern zur Last fallen und früher oder später wieder aufgegeben.

Was ist Qualitätssicherung?

Die erste Frage, die in diesem Zusammenhang beantwortet werden muss, lautet: Warum sollte man Qualitätssicherung durchführen? JavaScript ist in den Maßstäben des Internets mittlerweile eine alte Sprache, es existiert seit 1995, damals noch als „LiveScript“. Seit diesen Anfängen wird JavaScript häufig dazu eingesetzt, sehr schnell visuelle Ergebnisse im Browser zu erzeugen. Diese Möglichkeit, sehr schnell Vorzeigbares zu produzieren, hat dazu geführt, dass in JavaScript häufig nach dem Motto „quick and dirty“ vorgegangen wird. In Wahrheit sind die Ergebnisse hier allerdings nur sehr kurzlebig und der anfängliche Geschwindigkeitsvorteil stellt sich sehr bald als Nachteil heraus. Bei der Entwicklung mit JavaScript sollte wie bei anderen Sprachen auf einige Dinge geachtet werden. Das sind im Einzelnen: Stabilität, Erweiterbarkeit und Einfachheit.

Stabilität in Anwendungen beschreibt, wie robust die Software gegenüber Interaktionen ist. Eine stabile Software kann mit fehlerhafter oder falscher Benutzung umgehen. Hierunter fällt im JavaScript-Kontext beispielsweise: Was passiert, wenn ein Benutzer zweimal schnell hintereinander auf einen Button zum Abschicken eines Formulars klickt? Werden zwei Ajax Requests an das Backend abgesendet und führen diese dazu, dass zwei Datensätze erstellt werden?

Erweiterbarkeit bedeutet, dass die Software nicht nur die ursprünglichen Anforderungen erfüllen kann, sondern die Entwickler auch zukünftige oder aber geänderte Anforderungen umsetzen können. Nach dem Quick-and-dirty-Ansatz müsste man hier sagen: „Zusätzliche Features kann man doch immer irgendwie einbauen“. Eine Anforderung, die mit der Erweiterbarkeit einhergeht, ist allerdings, dass die Erweiterungen möglichst preiswert umgesetzt werden können. Dabei ist zu berücksichtigen, zu welchem Zeitpunkt im Softwarelebenszyklus ein bestimmtes Feature oder ein Bug auftritt. Je später dies der Fall ist, also je fixierter die Anwendung ist, umso größer wird der Aufwand. Durch Maßnahmen der Qualitätssicherung können die Kosten der Erweiterung oder Fehlerbeseitigung allerdings signifikant gesenkt werden. So kann beispielsweise sichergestellt werden, dass durch eine Änderung an einer Stelle keine andere Funktionalität an einer anderen Stelle in der Software negativ beeinflusst wird.

Einfachheit von Quellcode und damit einer Anwendung zeichnet sich nicht dadurch aus, dass die „bells and whistles“, die eine Anwendung für den Nutzer attraktiv machen, nicht umgesetzt werden können, weil sie eben nicht einfach sind. Einfachheit bezieht sich vielmehr auf die einfachste technische Umsetzung eines Features. Ein Entwickler sollte sich immer die Frage stellen: Was will ich mit meiner aktuellen Aufgabe erreichen und welcher Quellcode ist dafür notwendig? Eine Anforderung sollte stets auf möglichst direktem und technisch solidem Weg umgesetzt werden. Das verhindert, dass der Quellcode unnötig komplex wird. Die unnötige Komplexität von Software ist ein großes Problem, wenn es sich um langlebige Software handelt, die über ihren gesamten Lebenszyklus erweitert werden soll oder wenn sich das Team über die Projektlaufzeit ändert und Entwickler es verlassen und neue Personen hinzukommen, die erst in den bestehenden Quellcode eingearbeitet werden müssen.

Was haben diese Punkte nun mit Qualitätssicherung zu tun? Die vorgestellten Punkte sind die Basis von professioneller Software, und sie lassen sich nur nachhaltig durch eine funktionierende Qualitätssicherung erreichen.

Continuous Integration und Continuous Inspection

Continuous Integration und Continuous Inspection bilden die Basis für eine flexible und gesicherte Softwareentwicklung. Beide Praktiken haben in anderen Sprachen wie Java oder PHP schon lange Einzug gehalten. Aber auch im JavaScript-Umfeld gewinnt die kontinuierliche Qualitätssicherung immer mehr an Bedeutung.

Continuous Integration bezeichnet die Integration einzelner Bestandteile oder Module einer Applikation in das Gesamtsystem. Den Hintergrund dazu bildet die Idee, dass ein Entwickler meist an abgegrenzten Teilen einer Software arbeitet und nicht immer das Gesamtsystem im Blick haben kann, beziehungsweise nicht sämtliche Testfälle bei jeder Änderung prüfen kann. Continuous Integration funktioniert, indem bei jedem Einchecken in das Versionskontrollsystem bestimmte Aktionen wie beispielsweise die automatisierte Ausführung von Tests angestoßen werden. Continuous Integration beschreibt also, wie sich die Software während der Laufzeit verhält.

Continuous Inspection beschäftigt sich mit der Qualität des Quellcodes. Hierbei fällt häufig der Begriff „Technical Debt“. Das sind die technischen Schulden, die im Verlauf der Entwicklung aufgebaut werden. Technische Schulden werden mit jeder zusätzlichen Programmzeile aufgebaut. Jedes Statement im Quellcode erhöht die Komplexität der Anwendung und führt so zu einer Erhöhung der technischen Schulden. Diese Tatsache ist allerdings normal und im Alltag auch unumgänglich. Problematisch wird die Situation erst, wenn übermäßig viele technische Schulden aufgebaut werden. Das ist der Fall, wenn Konventionen oder Standards außer Acht gelassen werden, um ein bestimmtes Ziel wie die Fertigstellung eines Features zu einem bestimmten Zeitpunkt zu erreichen. Je mehr von diesen technischen Schulden aufgebaut werden, desto teurer wird die Entwicklung von neuen Features, aber auch die Behebung bestehender Fehler in der Software, da der Quellcode zunehmend schlechter zu erweitern und zu warten ist. In vielen Projekten hat es sich mittlerweile bewusst etabliert, technische Schulden aufzubauen, diese allerdings später in gezielten Aktionen wieder abzubauen.

QA-Plattformen

Um aber die Qualität in einem Projekt auf einem hohen Niveau zu halten und mit technischen Schulden umgehen zu können, ist eine Plattform notwendig, die den Status des Projekts transparent macht. Dadurch ist jedem, der an dem Projekt arbeitet, zu jedem Zeitpunkt bekannt, wo das Projekt im Bereich Qualität steht. Nur so kann das Projekt kontinuierlich überwacht werden und, falls notwendig, können gezielt Maßnahmen zur Qualitätsverbesserung geplant, durchgeführt und überwacht werden.

Ziel der Qualitätssicherung ist, es dem Entwickler so einfach wie möglich zu machen, qualitativ hochwertigen Quellcode zu entwickeln. Dabei sollen die Werkzeuge im Hintergrund stehen und für den Entwickler keinen unnötigen Mehraufwand erzeugen.

Die Plattformen zur Qualitätssicherung lassen sich unterteilen in IDE-basierte Werkzeuge und solche, die in eine Continuous-Integration-Plattform integriert werden. Im Folgenden wird exemplarisch PHPStorm als IDE verwendet. Die beschriebenen Werkzeuge können auf ähnliche Weise auch in andere IDEs, beispielsweise Eclipse, integriert werden. Als Continuous-Integration-Umgebung kommt Jenkins [1] zum Einsatz. Beide Plattformen wurden aufgrund ihrer weiten Verbreitung, der allgemeinen Verfügbarkeit und der guten Werkzeugunterstützung gewählt.

Die vorhandenen Werkzeuge sollen die kontinuierliche Qualitätssicherung vor allem in einem wichtigen Aspekt unterstützen, und zwar in der schnellen Rückmeldung an den Entwickler. Bei der Qualitätssicherung ist es wesentlich, dass der Entwickler schnell die Ergebnisse der Analysen und Tests vorliegen hat. Ist das der Fall, befindet er sich meist noch im Kontext der Aufgabe und kann auf eventuelle Probleme schnell reagieren und sie beheben. Eine lange Zeitspanne zwischen der Entwicklung des Quellcodes und den Ergebnissen der Continuous Inspection und Continuous Integration bedeutet, dass sich der Entwickler mit hoher Wahrscheinlichkeit in der Zwischenzeit bereits mit anderen Aufgaben befasst und sich erst wieder in das Thema einarbeiten muss.

Für den Entwickler ist die IDE als Plattform zur Qualitätssicherung sehr interessant, da hier eine Reihe von Werkzeugen schon während der Entwicklung zur Verfügung steht. Diese werden als Plug-ins eingebunden. In PHPStorm erreicht man die Plug-in-Verwaltung über Preferences | Plugins (Abb. 1) Hier hat der Entwickler die Möglichkeit, zusätzliche Plug-ins aus einem Repository im Internet oder von der lokalen Festplatte hinzuzufügen und es im Anschluss zu aktivieren.

Abb 1: PHPStorm Plug-in-Verwaltung

Die Continuous-Integration-Plattform, in unserem Fall Jenkins, ist ein Stück weiter vom direkten Coding entfernt als die IDE. Die Aufgabe dieser Plattform besteht darin, das Gesamtsystem zu überwachen. Zu diesem Zweck wird das Projekt in möglichst kurzen Abständen mit allen zur Verfügung stehenden Tools überwacht. Dieser Vorgang wird als „Build“ bezeichnet. Für die einzelnen Tools können Grenzwerte definiert werden, bis zu denen ein Build als erfolgreich gilt. Werden diese Werte überschritten, ist der Build fehlgeschlagen. In diesem Fall sollte das gesamte Entwicklerteam die aktuellen Aufgaben ruhen lassen und sich gemeinsam um die Beseitigung der Probleme kümmern, die zum Fehlschlag des Builds geführt haben. Für die Ausführung der einzelnen Werkzeuge wird in Jenkins kein Plug-in benötigt. Die entsprechenden Kommandos können entweder als Windows-Batch-Befehl, als Unix-Shell-Befehl, Ant Task oder Maven Target ausgeführt werden. Ziel ist es, dass die verschiedenen Tools ihre Ausgabe in Dateien schreiben, die innerhalb von Jenkins einem bestimmten Build zugeordnet und entsprechend angezeigt werden. Zur Visualisierung der Ergebnisse werden wiederum Plug-ins benötigt. Diese können entweder über das Jenkins Plugin Repository oder aus einer lokalen *.hpi-Datei installiert werden. Nach einem Neustart von Jenkins steht das neu installierte Plug-in zur Verfügung. Abbildung 2 zeigt die Jenkins-Konfiguration.

Abb 2: Jenkins-Konfiguration

Continuous Integration und Versionskontrolle

Damit die Arbeit im Team und die Qualitätssicherung funktionieren können, wird ein Versionskontrollsystem im Projekt benötigt. Für Projekte im Webumfeld setzt sich zunehmend Git als führendes Versionskontrollsystem gegenüber anderen Systemen wie SVN oder Mercurial durch. Für alle größeren Systeme auf dem Markt existiert eine gute Integration sowohl in die IDE als auch in Jenkins.

In PHPStorm ist die Git-Integration als Plug-in ein fester Bestandteil der Distribution. Der Entwickler muss sich deshalb hier um nichts weiter kümmern, als die Repository-Informationen des Projekts bekannt zu machen. Innerhalb des Projekts steht dann über das Kontextmenü im Dateisystembrowser der Punkt Git zur Verfügung, über den die verschiedenen Operationen wie Hinzufügen zum Versionskontrollsystem oder Commit erreichbar sind.

Jenkins unterstützt standardmäßig nur die Versionskontrollsysteme CSV und SVN. Um Git hinzuzufügen, muss Jenkins Git Plugin installiert werden. Nach einem Neustart des Jenkins-Dienstes ist im Projektsetup unter den verfügbaren Versionskontrollsystemen als zusätzliche Option Git vorhanden. Hier kann unter anderem ein Git Repository eingetragen werden, das auf Änderungen überwacht werden soll. Unter dem Konfigurationspunkt Build Triggers kann dann konfiguriert werden, in welchen Zyklen das Versionskontrollsystem auf Änderungen geprüft werden soll. In diesem Artikel wird aus Platzgründen nicht näher auf Ant zur Konfiguration von Jenkins Tasks eingegangen, stattdessen werden die notwendigen Kommandos als Unix-Shell-Kommandos verwendet.

Die folgenden Abschnitte gehen auf verschiedene Werkzeuge ein, die im Rahmen der Qualitätssicherung in JavaScript eine Rolle spielen. Außerdem wird gezeigt, wie diese in die jeweilige Plattform integriert werden können und was dem Entwickler daraus für Nutzen entsteht.

[ header = Qualitatives JavaScript – Teil 2 ]

jslint

Ein sehr weit verbreitetes Werkzeug zur Qualitätssicherung in JavaScript ist JSLint [2]. JSLint parst den übergebenen JavaScript-Quelltext und prüft ihn auf Syntaxfehler und bekannte Antipatterns in der Entwicklung. Das Werkzeug wurde von Douglas Crockford entwickelt und stellt ein Hilfsmittel dar, die Empfehlungen korrekt umzusetzen, die er in seinem Buch „JavaScript: The good parts“ beschreibt und näher erläutert. Das Ziel liegt dabei darin, dass die Vorteile von JavaScript als Programmiersprache voll ausgenutzt werden sollen und die, teils auch historisch gewachsenen, Nachteile möglichst vermieden werden sollen. Einige Beispiele für Warnungen von JSLint sind die Verwendung von eval, inkrement- und dekrement-Operatoren oder continue.

Für die Verwendung von JSLint in PHPStorm muss kein zusätzliches Plug-in installiert werden. JSLint ist standardmäßig ein fester Bestandteil der IDE. Diese bietet in der Konfiguration unter dem Punkt Javascript | Code Quality Tools die Option JSLint. Hier kann das Werkzeug für das Projekt aktiviert oder deaktiviert werden. Außerdem steht dem Entwickler die Möglichkeit zur Verfügung, JSLint hier zu konfigurieren und festzulegen, welche Warnungen ignoriert werden sollen.

Um JSLint in Jenkins einzubinden, wird die Kommandozeilenversion des Werkzeugs benötigt. Es kann beispielsweise „jslint4java“ verwendet werden. Dieses Tool liegt als .jar-Datei vor, die idealerweise im Suchpfad des Jenkins-Nutzers liegen sollte. Dann kann JSLint mit einer einfachen Kommandozeile eingebunden werden. Hierfür wählt man über den Button Add build step den Punkt Execute shell und trägt dann die folgende Kommandozeile ein:

java -jar jslint4java.jar –report xml /path/to/src/*.js > jslint.xml

Dieser Befehl sorgt dafür, dass sämtliche Dateien im angegebenen Verzeichnis, die auf .js enden, mit JSLint geprüft werden. Die Ausgabe erfolgt im XML-Format, was die spätere Darstellung in Jenkins erleichtert. Als Letztes wird die Ausgabe in eine Datei umgeleitet. Die Angaben von Dateien in Jenkins beziehen sich immer auf den aktuellen Workspace. Das bedeutet, dass sich ein Entwickler keine Gedanken über absolute Pfade oder Konflikte mit anderen Projekten machen muss. Die angegebenen Dateien liegen in einem Verzeichnis, das exklusiv für das aktuelle Projekt verwendet wird. Sowohl die Build Steps als auch die spätere Visualisierung beziehen sich auf diesen Workspace.

Zur Anzeige der von JSLint gefundenen Fehler kann das Jenkins Violations Plugin verwendet werden. Dieses Plug-in erwartet eine standardisierte XML-Datei als Eingabe und deckt damit nicht nur ein einzelnes Tool wie JSLint, sondern eine ganze Reihe von Analysetools ab. Hierunter fallen unter anderem Programme wie beispielsweise checkstyle, PHPCS oder pmd [3].

Der Report über die Violations ist innerhalb des Projekts unter dem Punkt Violations verfügbar. Hier kann man verschiedene Informationen abrufen wie den Typ und die Anzahl der Violations oder die Anzahl der Dateien mit Violations. Außerdem steht dem Betrachter eine Grafik über die Entwicklung der Anzahl der Violations über alle Builds zur Verfügung.

JSLint deckt allerdings nur einen Teil der statischen Codeanalyse ab. Hier wird vor allem auf syntaktische Korrektheit und bekannte Antipatterns geprüft. Ein anderer Bereich der statischen Codeanalyse ist das Aufspüren von mehrfach vorkommenden Codeblöcken, mit dem sich der folgende Abschnitt befasst.

Copy/Paste Detector

In der Programmierung ist es kurzfristig oft einfacher, existierende Codestellen, die an anderer Stelle ebenfalls benötigt werden, einfach zu kopieren, anstatt sie sauber herauszulösen und an mehreren Stellen wiederzuverwenden. Der Einsatz von so genanntem „Copy and Paste“ wirkt sich mittel- bis langfristig negativ auf die Software aus und macht die anfängliche Zeitersparnis schnell zunichte, da die Wartbarkeit der Software stark eingeschränkt wird. Ein anderes Problem im Zusammenhang mit dupliziertem Code kennen die meisten Softwareentwickler wahrscheinlich aus dem täglichen Leben: Ein Fehler ist behoben, einige Zeit später beschwert sich der Kunde, dass der angeblich bereits behobene Fehler erneut auftritt. Eine kurze Recherche im Quellcode ergibt, dass der Bugfix immer noch im Quellcode vorhanden ist. Erst nach einer weiteren Analyse stößt man darauf, dass der fehlerhafte Code auch noch an anderen Stellen in der Software verwendet und dort bisher noch nicht behoben wurde. Hier erleichtern es verschiedene Werkzeuge dem Entwickler, duplizierte Codestellen zu identifizieren und im Anschluss zu extrahieren und zu verallgemeinern.

In PHPStorm ist die Unterstützung zur Suche nach dupliziertem Code fester Bestandteil der Anwendung. Über das Code-Menü erreicht man den Punkt Locate Duplicates…. Hier kann man aus verschiedenen Optionen wählen, um den Suchradius einzuschränken. Es empfiehlt sich allerdings, in regelmäßigen Abständen das gesamte Projekt zu durchsuchen. Nachdem der Bereich festgelegt wurde, in dem gesucht wird, muss festgelegt werden, in welchen Sprachen nach dupliziertem Code gesucht werden soll, in unserem Fall ist das „JavaScript“. Als Nächstes kann man festlegen, wie mit Variablen, Funktionen und Literalen umgegangen werden soll, beziehungsweise ob sie anonymisiert werden sollen. Eine Anonymisierung führt dazu, dass sich das Tool nicht durch unterschiedlich benannte Variablen oder Funktionen überlisten lässt. Zu guter Letzt muss noch ein Schwellwert festgelegt werden, ab dem Quellcode als Duplikat angesehen wird. Je nach Projektgröße und -struktur muss hier ein sinnvoller Wert gefunden werden, damit nicht im ersten Schritt schon zu viele Duplikate gefunden werden. Es empfiehlt sich hier ein iterativer Ansatz, bei dem der Grenzwert schrittweise verschärft wird. Außerdem sollte Quellcode, der vom Entwickler nicht direkt beeinflusst werden kann, wie beispielsweise Bibliotheken wie jQuery oder Ähnliches nicht geprüft werden, da dies zu unnötigen Meldungen führen kann. Die gefundenen Stellen werden in einem separaten Toolfenster angezeigt. Die Datei kann dann per Doppelklick in den Editor geladen werden und das Duplikat aufgelöst werden.

Die Integration in Jenkins gestaltet sich ähnlich wie schon die von JSLint. Es muss lediglich ein weiterer „Build Step“ hinzugefügt werden:

/opt/PMD/bin/run.sh cpd --minimum-tokens 12 --files /path/to/src --language ecmascript --format xml > cpd.xml

Als Basisplattform für die Copy/Paste Detection dient PMD. Dieses Werkzeug stammt ursprünglich aus der Java-Welt und dient dort zum Auffinden potenzieller Fehler, ungenutztem Code oder komplizierten Ausdrücken. PMD wurde über die Zeit immer weiter entwickelt und dabei wurden weitere Sprachen wie beispielsweise JavaScript integriert.

Wichtig an dieser Kommandozeile ist die Anzahl der Tokens, die geprüft werden, also einzelne logische Einheiten der Sprache. Hier muss ein vernünftiges Maß gefunden werden, damit nicht zu viele Duplikate gefunden werden. Die Option language gibt an, dass Dateien im ECMAScript-Standard geprüft werden sollen. Das Ausgabeformat ist XML und wird in eine entsprechende Datei umgeleitet.

Sowohl JSLint als auch die Copy/Paste Detection fallen in die Kategorie der statischen Codeanalyse. Der Quellcode wird dabei direkt analysiert, die Anwendung muss dazu nicht ausgeführt werden. Ein anderes Gebiet sind Softwaretests. Hier wird die Software ausgeführt und ihre Teile werden auf deren Funktionsfähigkeit geprüft.

Unit Tests

Für JavaScript existieren mittlerweile mehrere Testframeworks. Fast jede größere Library bringt mittlerweile ihr eigenes Framework mit, beispielsweise qunit von jQuery oder doh von dojo. Es gibt allerdings auch unabhängige Testframeworks wie jsTestDriver [4] oder Jasmine [5]. Im Weiteren werden wir uns mit einer Kombination von Jasmine und jsTestDriver beschäftigen. Jasmine dient dabei zur Formulierung der Tests, und jsTestDriver stellt die Infrastruktur zur Integration der Tests in die jeweilige Plattform zur Verfügung. Verbunden werden beide Werkzeuge durch den JasmineAdapter [6], der die Übersetzung der Jasmine-Befehle in den Befehlssatz von jsTestDriver übernimmt.

Das erste Ziel ist die Integration von Jasmine Unit Tests direkt in PHPStorm. Zu diesem Zweck existiert das JSTestDriver Plugin. Ist es installiert, müssen vom Entwickler noch ein paar Voraussetzungen geschaffen werden, damit die Tests ausgeführt werden. Im ersten Schritt werden natürlich der Quellcode, der getestet werden soll, und die Tests benötigt. Hier empfiehlt es sich, beides in getrennten Ordnerstrukturen abzulegen, den Quellcode im Verzeichnis src und die Tests im Verzeichnis spec. Als Nächstes muss eine Konfigurationsdatei für den jsTestDriver erstellt werden. Das ist eine Textdatei, in der angegeben wird, wo die verschiedenen Dateien gefunden werden können. Normalerweise wird sie mit der Endung .jstd versehen, die verdeutlicht, dass es sich hierbei um die Konfiguration des jsTestDrivers handelt:

load:   - ../jasmine/jasmine.js   - ../jasmine/JasmineAdapter.js   - spec/myTest.js   - src/mySource.js

Nachdem diese Voraussetzungen erfüllt sind, kann man den JsTestDriver Server starten. Dazu öffnet man in PHPStorm das Toolfenster JsTestDriver Server. Hier gibt es zuerst die Möglichkeit, über ein grünes Pfeilsymbol den Server zu starten. Danach kann man auf eines oder mehrere der fünf angezeigten Browsersymbole klicken, um den jeweiligen Browser beim jsTestDriver zu registrieren und später die Tests auf diesem Browser auszuführen. Der letzte Schritt besteht schließlich in der eigentlichen Ausführung der Tests. Hierfür wählt man im Kontextmenü der .jstd-Datei den Punkt Run ‚….jstd‘ aus. Der Testablauf wird in einem separaten Run-Tool-Fenster ausgegeben, wo man über Erfolg oder Fehlschlag der verschiedenen Tests informiert wird. Durch die Kombination von Jasmine und jsTestDriver besteht für den Entwickler die Möglichkeit, die erstellten Tests zu gruppieren, sie sehr häufig ablaufen zu lassen und dabei sofort die Rückmeldung zu erhalten, ob die Tests erfolgreich waren. Diese leichtgewichtige Ausführung und die schnelle Rückmeldung sind die Voraussetzung für Programmiertechniken wie beispielsweise Test-driven Development (TDD), wo zuerst der Test und danach dann der zugehörige Quellcode erstellt wird.

Für einen Entwickler ist es nicht sonderlich praktikabel, während der Entwicklung sämtliche Unit Tests eines Projekts ablaufen zu lassen. In einem größeren Projekt kommen schnell mehrere hundert und sogar bis zu Tausenden Unit Tests zusammen. Hier dauert auch ein Testdurchlauf normalerweise länger, was wiederum gegen eine schnelle Rückmeldung gerade beim TDD spricht. Aber auch hierfür gibt es eine Lösung. Die Tests können, wie die übrigen Werkzeuge auch, in die Continuous-Integration-Umgebung integriert werden. Einzige Voraussetzungen, die hierfür zu erfüllen ist, ist eine funktionsfähige Installation des jsTestDrivers auf dem Jenkins Server und ein oder mehrere Browser, die sich beim Server registrieren. Die Installation stellt kein weiteres Problem dar, da der jsTestDriver als .jar-Datei zur Verfügung steht und so sehr einfach über die Kommandozeile ausgeführt werden kann. Idealerweise sollte durch ein init-Script dafür gesorgt werden, dass der jsTestDriver Server immer läuft. Auch die Registrierung der Browser sollte möglichst automatisiert werden. Zur eigentlichen Einbindung der Tests ist, wie bei den bereits vorgestellten Tools auch, nur eine Kommandozeile erforderlich:

java -jar JsTestDriver.jar –config /path/to/config.jstd --tests all --testOutput . --reset

Die .jstd-Datei, die auch schon in PHPStorm verwendet wurde, kann auch hier benutzt werden, sie muss lediglich um die Direktive server: http://localhost:9876 erweitert werden. Sie gibt lediglich an, wo sich der jsTestDriver Server befindet, und dient dazu, dass die Tests korrekt ablaufen können.

jsTestDriver generiert xUnit-kompatible Ausgabe im XML-Format. Das erleichtert die Visualisierung der Ergebnisse, da hier ein Standard-Plug-in von Jenkins, nämlich das xUnit Plugin, verwendet werden kann. Über den Add-Button in der Konfiguration dieses Plug-ins kann ein neuer Abschnitt vom Typ JUnit hinzugefügt und der Name der Testdateien angegeben werden. Hier ist es auch zulässig, Suchmuster für den Dateinamen wie beispielsweise TEST-Firefox*.xml zu verwenden. Die Ergebnisse der Tests können dann über den Menüpunkt Test Result im jeweiligen Jenkins-Projekt angezeigt werden. Hier erhält man die Informationen, ob ein Test erfolgreich war oder nicht, wie lange er gedauert hat und etliche weitere Informationen. Die Tests sind jeweils in Pakete gruppiert, die die verschiedenen Dateien widerspiegeln. In der nächsten Ebene wird weiter nach Klassen unterschieden und schließlich auf die Ebene der einzelnen Tests gegangen.

Fazit

Neben den vorgestellten Werkzeugen gibt es noch eine Reihe weiterer Hilfsmittel, um die Qualität von JavaScript-Quellcode kontinuierlich zu überwachen und aufgrund der daraus gewonnenen Erkenntnisse auch kontinuierlich zu verbessern. Hierunter fallen beispielsweise die Abdeckung der Software mit Tests, die so genannte „Code Coverage“. Außerdem sind unter anderem Komplexitätsanalysen oder die Suche nach ungenutztem Code in der Anwendung relevant. Ein weiteres Feld der Qualitätssicherung sind Lasttests, die sich ebenfalls in eine Continuous-Integration-Plattform integrieren lassen.

Wichtig ist bei der Qualitätssicherung, dass sich das Entwicklerteam auf einen Standard für die Codequalität einigt und eine gemeinsame Vorgehensweise entwickelt, um möglichst hochwertigen Quellcode zu erstellen. Steht nicht jeder Entwickler im Team hinter diesen Richtlinien, wird es sehr schwer, sie auf mittlere bis lange Frist durchzusetzen. Die Qualitätssicherung in einem Projekt erfordert sehr viel Disziplin und Motivation von allen Beteiligten.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -