AngularJS testen
Auch Anwendungen die auf JavaScript-MVC-Frameworks wie AngularJS aufbauen können mittels TDD entwickelt werden. Wie einfach dies ist hängt davon ab ob das jeweilige Framework dafür ausgelegt ist. Bei AngularJS wurde nicht nur an TDD gedacht sondern es gibt sogar eine (ausführliche) offizielle Dokumentation die zeigt wie man vorgehen soll.
Dependency Injection macht’s möglich
AngularJS setzt sehr stark auf Dependency Injection. Wenn alle Abhängigkeiten wie Services, Libraries und sogar der DOM an die eigenen Methoden übergeben wird braucht man selber keine fixen Abhängigkeiten mit new zu erzeugen. Fürs testen genügt es so die Abhängigkeiten zu simulieren ohne das man auf den konkreten Service oder den ganzen DOM angewiesen ist.
Bei AngularJS empfiehlt nicht nur die Dokumentation diese Vorgehensweise, sondern es ist auch der einfachste Weg um mit dem Framework zu arbeiten. Dadurch sind die meisten Anwendungen in einer guten Ausgangsposition um automatisch getestet zu werden.
Angular-seed als Startpunkt
Wie in meinem früheren Beitrag gezeigt kann man sehr einfach die passenden Bibliotheken einbinden um die eigene Anwendung mit AngularJS zu ergänzen. Will man AngularJS voll ausnützen gibt es aber eine praktische Abkürzung: angular-seed
Angular-seed ist ein Anwendungsskelett für AngularJS das bereits alles nötige enthält um mit TDD loslegen zu können. So sind neben einer minimalen Projektstruktur sowohl Jasmine wie auch der Testrunner Karma bereits konfiguriert und einsatzbereit. Nach einer Installation von Node.js genügt es das Script scripts\test.bat
für die Unit- und script/e2e-test.bat
für die Integrationstests zu starten.
Szenarien mit Jasmine beschreiben
Jasmin ist ein BDD Framework (Behaviour-driven Development) für JavaScript und lässt einem Szenarien (Testfälle) sehr ähnlich wie RSpec oder MSpec beschreiben. Ein einfacher Test ob die Addition wie erwartet funktioniert kann so beschreiben werden:
Die Testdurchführung geschieht entweder im Webbrowser oder alternativ mit den Testrunner Karma. Dieser überwacht die JavaScript-Dateien im Projekt und führt die Tests aus sobald sich etwas ändert. Das Resultat wird einem in der Konsole angezeigt und sieht im Erfolgsfall so aus:
Im Fehlerfall (hier mit einem – statt einem +) zeigt einem Karma was nicht stimmt:
Asynchrone Operationen testen
Das Testen von asynchronen Methoden in Jasmine hat seine eigenen Herausforderungen. Jonathan Paul hat sehr gut beschrieben wo diese liegen und wie man seine Testfälle schreiben muss um die gewünschten Resultate zu erhalten.
Allerdings ist dies recht mühsam diesen Code zu lesen. Die Erweiterung Jasmine.Async von Derick Bailey liefert einem eine kleine Verbesserung. So braucht man nicht immer wieder die gleichen Codeblöcke zu schreiben und kann sich stattdessen auf ein async.beforeEach oder async.it beschränken.
End-to-End Tests
Oft möchte man aber wissen ob die ganze Anwendung funktioniert und nicht nur die einzelnen Teile. Dazu sind die ebenfalls mit angular-seed mitgelieferten End-to-End Tests gedacht.
Als Anwendung nutze ich für dieses Beispiel wiederum den JSON-Service aus "Erste Schritte mit AngularJS". Diese Spezifikation beschreibt was für einen MD5-Hash ich für den Text "Hello" erwarte:
Diese Tests lassen sich entweder durch Karma oder direkt über den Webbrowser starten:
Die hier gezeigten Beispiele vermitteln einen ersten Eindruck der Möglichkeiten. Wer mehr dazu wissen will sollte sich diese Webseiten und Videos anschauen:
- Pluralsight-Kurs Testing Clientside JavaScript
- Offizielle Webseite von Jasmine
- Testing Your JavaScript with Jasmine
- Full-Spectrum Testing with AngularJS and Karma
- AngularJS Best Practices: I’ve Been Doing It Wrong
- Angular JS – 9 (End to End Testing – manual)
- Test Driven Development with KnockoutJS, VisualStudio, and Karma
- Chutzpah (JavaScript Test Runner für Visual Studio)
Fazit
AngularJS wurde so geschrieben das man damit testgetriebene Anwendungen entwickeln kann. Durch Erweiterungen wie angular-seed und Jasmine.Async hat man die nötigen Werkzeuge zur Hand um sehr einfach mit dem Testen beginnen zu können. Alles was es nun noch braucht ist die Bereitschaft dies auch wirklich zu machen. Und das notwendige Training um auch schnell vorwärts zu kommen.