Zum Inhalt

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:

'use strict';

describe('jasmine demo', function() {

  describe('calculator', function() {
    it('should return the sum of two values', function() {
      expect(1 + 2).toEqual(3);
    });
  });
});

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:

karma_green

Im Fehlerfall (hier mit einem – statt einem +) zeigt einem Karma was nicht stimmt:

karma_red

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:

'use strict';

describe('md5 Service', function() {

  beforeEach(function() {
    browser().navigateTo('../../app/md5service.html');
  });


  it('should have a button to click', function() {
    expect(element('button').text()).toEqual('Click');
  });

  it('should ask service for md5-hash of "Hello"', function() {
    input('input').enter("Hello");
    element('button').click();
    expect(element('.result').text())
      .toEqual('8b1a9953c4611296a827abf8c47804d7');
  });
});

Diese Tests lassen sich entweder durch Karma oder direkt über den Webbrowser starten:

angular_end2end_runner

Mehr zum Thema

Die hier gezeigten Beispiele vermitteln einen ersten Eindruck der Möglichkeiten. Wer mehr dazu wissen will sollte sich diese Webseiten und Videos anschauen:

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.