© istockphoto.com/wasabii
Von Unit-Tests und E2E-Tests mit Angular

Angular Testing


Tests schaffen Sicherheit, dokumentieren und regen zum Nachdenken an. Das gilt vor allem, wenn Sie im Team über längere Zeit an einer Applikation arbeiten. Mit Angular als Framework für Ihre Applikation sind Sie jedoch auch für diese Herausforderung bestens gewappnet. Dabei setzt Angular auf verbreitete Standards und Bibliotheken und erweitert sie um frameworkspezifische Details, um Ihnen das Testen Ihrer Applikation so einfach wie möglich zu gestalten.

Leider werden viele Angular-Applikationen nicht oder nur unzureichend getestet. Das liegt zum einen an der Bequemlichkeit der Entwickler, zum anderen aber auch an einer gewissen Einstiegshürde. In diesem Artikel möchte ich Ihnen zeigen, wie Sie die Werkzeuge, die Ihnen Angular bietet, benutzen können, um Ihre Applikation abzusichern. Dabei werden Sie sehen, dass das Erzeugen von Tests keineswegs eine Strafaufgabe sein muss.

Grundlagen

Beim Thema Tests stolpern Sie recht schnell über das Konzept der Testpyramide. Das Konzept besagt, dass es verschiedene Arten von Tests gibt und Sie unterschiedlich viele Tests pro Kategorie benötigen. Die Basis der Testpyramide bilden Unit-Tests, die zahlenmäßig die meisten Tests stellen. Sie werden während der Entwicklung sehr häufig ausgeführt und sollten aus diesem Grund sehr wenig Laufzeit benötigen. Unit-Tests prüfen nur einzelne Codestücke, in den meisten Fällen handelt es sich dabei um Funktionen. Die nächsten beiden Ebenen, die Integrations- und Akzeptanztests, testen nicht mehr nur einzelne unabhängige Codefragmente, sondern größere Einheiten bis hin zur grafischen Oberfläche. Die Anzahl dieser Tests ist wesentlich geringer als die der Unit-Tests, allerdings ist die Laufzeit auch wesentlich länger, da die Tests das gesamte System einbeziehen.

Bei Angular-Applikationen unterscheidet man, ähnlich wie bei der Testpyramide, zwischen zwei Kategorien von Tests: Unit-Tests und End-to-End-Tests. Diese Unterscheidung wird nötig, da sie auf unterschiedliche Technologien setzen: Unit-Tests werden auf Basis von Jasmine und Karma entwickelt, End-to-End-Tests – auch kurz E2E-Tests – verwenden dagegen Protractor. In welchen Fällen setzen Sie nun auf Unit-Tests, und wann sollten Sie lieber einen E2E-Test erstellen? Wenn Sie tiefer in das Thema Testing eintauchen, werden Sie schnell merken, dass gerade Benutzerinteraktionen und Workflows recht umständlich mit Unit-Tests abzudecken sind. Das ist der klassische Anwendungsfall für E2E-Tests: Eine Tastatureingabe, ein Klick auf einen Button und dann warten, dass die Applikation mit der korrekten Ausgabe reagiert. Mit Unit-Tests dagegen sichern Sie einzelne Methoden ab: Liefert das Observable bei einer bestimmten Wertekonstellation eines injizierten Service die korrekten Werte, und wird bei einer Fehleingabe die korrekte Exception ausgelöst? All das sind Dinge, die Sie mit Unit-Tests abdecken.

Set-up

Das Aufsetzen einer Angular-Applikation gestaltet sich vergleichsweise aufwendig, sodass Sie dies in den seltensten Fällen selbst übernehmen, sondern stattdessen entweder auf vorgefertigte Templates oder andere Werkzeuge zurückgreifen sollten. Als sehr hilfreich hat sich in diesem Bereich das Angular CLI erwiesen. Mit diesem Kommandozeilenwerkzeug können Sie innerhalb kürzester Zeit mit der Entwicklung Ihrer Applikation starten. Neben dem Set-up von Angular und TypeScript übernimmt das Angular CLI auch die Installation und Konfiguration Ihrer Testumgebung. Um es auf Ihrem System zu installieren, führen Sie den Befehl npm install -g angular-cli aus. Im Anschluss daran können Sie das Werkzeug auf Ihrer Kommandozeile verwenden. Mit ng init in einem leeren Verzeichnis lassen Sie die Basisstruktur für Ihre Applikation erzeugen. Außerdem werden sämtliche Pakete heruntergeladen, die Sie üblicherweise für den Start einer neuen Angular-Applikation benötigen. Neben den Kernkomponenten von Angular werden auch Jasmine, Karma und Protractor installiert.

Das Angular CLI sorgt auch für eine einfache Testausführung: Sie können Ihre Unit-Tests von der Kommandozeile mit dem Befehl npm test ausführen. Diese als „npm Scripts“ bezeichneten Kommandos werden in der package.json-Datei Ihres Projekts in der Sektion „scripts“ festgelegt. Im Fall von npm test wird auf das Kommando ng test verwiesen – an dieser Stelle übernimmt das Angular CLI wieder die Kontrolle und führt die Tests aus. Die E2E-Tests Ihres Projekts führen Sie ebenfalls über die Kommandozeile mit der Eingabe npm run e2e aus.

Unit-Tests in Angular

Für Unit-Tests setzt Angular auf die bewährte Kombination von Jasmine und Karma. Jasmine ist ein sehr weit verbreitetes Testframework, das bereits in der ersten Version von Angular zum Einsatz kam. Bei der Erzeugung von Tests können Sie ohne Einschränkungen auf den kompletten Funktionsumfang von Jasmine zurückgreifen. Listing 1 zeigt Ihnen ein Beispiel für einen Test mit Jasmine, damit Sie sich mit den grundlegenden Elementen des Frameworks vertraut machen können. Die Beschreibung der einzelnen Komponenten können Sie Tabelle 1 entnehmen.

Listing 1: Test mit Jasmine

describe('Calculator', () => { let calc: Calculator; beforeEach(() => { calc = new Calculator(); }); it('should add 1 and 1 and return 2', () => { const result = calc.add(1, 1); expect(result).toEqual(2); }); });

Komponente

Beschreibung

beforeAll(), afterAll()

Set-up- und Tear-down-Routinen vor bzw. nach allen Tests

beforeEach(), afterEach()

Set-up- und Tear-down-Routinen vor bzw. nach jedem einzelnen Test

describe()

Testsuite zur Gruppierung von Tests

it()

Einzelner Testfall

expect().toEqual()

Assertion, Prüfung innerhalb eines Tests

Tabelle 1: Die wichtigsten Elemente von Jasmine

Die zweite Komponente, die Sie für die Ausführung von Unit-Tests benötigen, ist der Testrunner Karma. Er stellt die Infrastruktur zur Verfügung, auf der die Jasmine-Tests ausgeführt werden. Der wichtigste Teil von Karma ist der Server; dort werden ein oder mehrere Browser registriert. Der Server erhält eine Konfiguration und die Tests, die ausgeführt werden sollen, und schickt entsprechende Befehle an alle registrierten Browser, sodass diese die Tests ausführen. Die Ergebnisse werden an den Karma-Server zurückgesendet, der wiederum für die Darstellung der Ergebnisse sorgt. Führen Sie Ihre Tests mit dem Kommando npm test aus, werden sowohl Karma als auch der TypeScript-Compiler in einen watch-Modus versetzt. Das bedeutet, dass Ihr Quellcode bei jedem Speichern nach einer Änderung neu kompiliert und alle Unit-Tests automatisch ausgeführt werden. Dadurch erhalten Sie kontinuierlich Rückmeldung über den Zustand Ihrer Tests. Zunächst erzeugen wir nun Unit-Tests für verschiedene Bestandteile einer Angular-Applikation und widmen uns danach den E2E-Tests.

Komponenten testen

Die wichtigsten Bausteine einer Angular-Applikation sind unbestritten die Komponenten. Sie bestehen im Kern aus einer Komponentenklasse mit einem Decorator, der zusätzliche Metainformationen hinzufügt, einem HTML-Template, das für die Darstellung sorgt, und einem optionalen Style Sheet. Aus diesem Aufbau ergibt sich, dass Sie beim Testen einer Komponente nicht so vorgehen können, wie Sie es bei einfachen Klassen und Funktionen gewohnt sind. Da Angular selbst hier auch ein Stück beteiligt ist, müssen Sie auch beim Testen auf die Testing Utilities des Frameworks zurückgreifen, um sinnvolle Tests erzeugen zu können. Diese Hilfsmittel finden Sie im Modul @angular/core/testing.

Für den ersten Komponententest gehen wir von einer Task-Komponente als Beispiel aus. Diese Komponente verfügt über einen Titel, der den Task beschreibt, und einen Status, der angibt, ob der Task erledigt ist oder nicht. Außerdem weist die Komponentenklasse eine Toggle-Methode au...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang