Die Einführung von Component Harnesses in Angular stellt einen Paradigmenwechsel im Bereich des Komponententests dar. Anstatt wie bisher auf DOM-Selektoren zu setzen, erlaubt das neue Test-as-a-User-API ein interaktives, benutzerzentriertes Testverhalten, das sich näher an der tatsächlichen Nutzung durch Endanwender orientiert. Harnesses kapseln die Interaktion mit Komponenten hinter einer stabilen API und abstrahieren dabei vom zugrunde liegenden HTML, was nicht nur zu weniger brüchigen Tests führt, sondern auch zu besserer Lesbarkeit und Wartbarkeit.
Ein Harness besteht aus mehreren Schlüsselelementen: Harness Environment, Harness Loader und dem Component Harness selbst. Die Harness Environment definiert, wo die Tests ausgeführt werden – typischerweise in einem Testbed oder auch in einer Webdriver-basierten Umgebung. Harness Loader ist für das Laden von Component Harnesses zuständig. Der Component Harness wiederum ist eine Klasse, die die Interaktionen mit einer spezifischen Angular-Komponente kapselt.
Beispielhaft lässt sich die Verwendung anhand des Angular Material Button Harness API veranschaulichen. Statt beispielsweise einen Button über querySelector zu lokalisieren und dann ein click()-Event auszulösen, stellt das Harness eine Methode wie click() direkt zur Verfügung. Die Selektionslogik und das Wissen um interne DOM-Strukturen werden dem Test vollständig entzogen. Dies führt zu resilienteren Tests, die selbst dann stabil bleiben, wenn sich die interne Struktur der Komponente ändert – solange das Verhalten und die öffentliche API konsistent bleiben.
Ein praktisches Beispiel, das sowohl das Button- als auch das Select-Harness einsetzt, zeigt, wie gut sich diese Methodik für komponentenübergreifende Tests eignet. Das Testen wird auf diese Weise nicht nur robuster, sondern auch deklarativer. Statt zu testen, wie etwas geschieht, testet man, was geschieht.
Ein weiteres zentrales Element ist die Möglichkeit zur Erstellung benutzerdefinierter Harnesses. Am Beispiel eines Video Test Harness lässt sich die Idee vertiefen: Eine komplexe Komponente mit mehreren interaktiven Zuständen und Mediensteuerungen kann über ein individuell geschriebenes Harness strukturiert getestet werden – mit Methoden wie play(), pause() oder getCurrentTime(). Die Abstraktion dieser Details erlaubt dem Entwicklerteam einen stärker verhaltensorientierten Fokus im Testdesign, anstatt sich mit Implementierungsdetails aufzuhalten.
In Verbindung mit dem modularen Aufbau von Anwendungen, wie er in der Angular Academy App demonstriert wird, lässt sich zeigen, wie Harnesses nicht nur isolierte Komponenten, sondern auch komplexe Kompositionsmuster testbar machen. Diese Technik ist insbesondere dann essenziel
Wie der Angular Linker und der Angular Compatibility Compiler den Build-Prozess optimieren
Der Angular Linker stellt eine neuere Lösung dar, die den Angular Compatibility Compiler (ngcc) ersetzt. Im Wesentlichen sorgt der Linker dafür, dass eine teilweise mit Ivy kompilierte Angular-Bibliothek vor der Integration in eine Anwendung vollständig in das Ivy-Format konvertiert wird. Diese Änderung ist Teil des Übergangs von Angular zu Ivy, einer neuen Rendering-Engine, die ab Version 9 verfügbar ist. Der Angular Compatibility Compiler wird jedoch in zukünftigen Angular-Versionen, voraussichtlich nach Version 12.2, vollständig entfernt. Ab diesem Punkt werden Angular-Anwendungen nur noch teilweise Ivy-kompilierte Bibliotheken verwenden können.
Der Angular Compatibility Compiler wurde in früheren Angular-Versionen erforderlich, um die Kompatibilität zwischen der alten View Engine und der neuen Ivy-Engine zu gewährleisten. In Version 9 musste dieser Compiler manuell ausgeführt werden, bevor eine Angular-Anwendung gebaut, getestet oder gestartet werden konnte. Seit späteren Versionen jedoch wird der ngcc über das Angular CLI automatisch ausgeführt, wenn es notwendig ist. Es bleibt jedoch die Möglichkeit, den Compiler manuell zu starten, was vor allem dann sinnvoll ist, wenn man eine präzisere Kontrolle über den Kompilierungsprozess wünscht und die Kompilierungsgeschwindigkeit optimieren möchte.
Die manuelle Ausführung des Angular Compatibility Compilers ist vor allem dann notwendig, wenn eine neue Version einer Angular-Bibliothek installiert wird oder wenn zusätzliche Bibliotheken aus einem Paket-Registry hinzugefügt werden. Es wird empfohlen, den Compiler als Teil des Postinstall-Hooks in einem Git-Repository auszuführen. Auf diese Weise wird vermieden, dass man bei jeder zukünftigen Aktion auf den Compiler warten muss. Während der Ausführung des Compilers kann der Quellcode weiter bearbeitet werden.
Wichtige Optionen des Angular Compatibility Compilers ermöglichen eine noch detailliertere Steuerung des Kompilierungsprozesses. Eine dieser Optionen ist --create-ivy-entry-points, die dafür sorgt, dass in jedem Angular-Bibliothekspaket ein Unterverzeichnis für die Ivy-Kompilierung erstellt wird. Wenn diese Option nicht gesetzt wird, überschreibt der Compiler die ursprünglichen Bündel. Eine weitere nützliche Option ist --properties, mit der spezifische Formattypen für Bibliothekspakete festgelegt werden können, wie etwa es2015 oder browser. Die Option --target ermöglicht es, nur bestimmte Pakete zu kompilieren, was in größeren Projekten hilfreich ist.
Für eine noch gezieltere Steuerung der Kompilierung bietet sich die Option --use-program-dependencies an. Sie ermöglicht es, nur die Bibliotheken zu kompilieren, die im aktuellen Angular-Projekt tatsächlich verwendet werden. Dies ist besonders nützlich, wenn man mit Angular CDK und Angular Material arbeitet, da diese Bibliotheken viele einzelne Sub-Pakete beinhalten, die standardmäßig alle einzeln kompiliert werden, was die Kompilierungsgeschwindigkeit erheblich beeinflussen kann.
Ein weiterer bedeutender Punkt bei der Nutzung des Angular Compatibility Compilers ist die Wahl des richtigen Paketformats. Forschungen haben gezeigt, dass das es2015-Format für die Kompilierung von View Engine-kompatiblen Bündeln in Ivy-Bündel am schnellsten ist, gefolgt von dem module-Format. Eine Kombination aus verschiedenen Optionen kann hier die Kompilierungsgeschwindigkeit weiter optimieren.
Die Ausführung des Angular Compatibility Compilers in einer CI/CD-Umgebung kann jedoch eine Herausforderung darstellen. Oftmals wird empfohlen, nicht den gesamten node_modules-Ordner zu cachen, da dies zu lange dauert. Stattdessen sollte der Cache des Paketmanagers verwendet werden, um die Build-Zeiten zu verkürzen. In Fällen, in denen der Cache in der CI/CD-Umgebung nicht aktiviert ist, muss der Compiler bei jedem Durchlauf des Workflows erneut ausgeführt werden, was eine sorgfältige Planung und die Nutzung von Postinstall-Hooks erfordert.
Die manuelle Ausführung des ngcc bietet den Vorteil, dass der Prozess optimiert und angepasst werden kann, um die bestmögliche Geschwindigkeit zu erreichen. Beispielsweise kann eine spezifische Kombination von Optionen verwendet werden, um nur das notwendigste Format zu kompilieren. Eine typische Konfiguration für die manuelle Ausführung könnte so aussehen:
ngcc --first-only --properties es2015 module fesm2015 esm2015 browser main --create-ivy-entry-points
Diese Optionen sorgen dafür, dass nur das schnellste Paketformat – es2015 – als erstes kompiliert wird. Außerdem wird mit der Option --create-ivy-entry-points die Ivy-Kompilierung direkt auf das Zielpaket angewendet, anstatt das bestehende View Engine-Bündel zu überschreiben.
Es ist jedoch wichtig zu beachten, dass in den Versionen 9.0 und 11.1 von Angular die Option --create-ivy-entry-points möglicherweise nicht die beste Wahl ist. Hier kann eine In-Place-Kompilierung etwas schneller sein. Das Managen von Paketen, die zum ersten Mal verwendet werden, kann ebenfalls mit der Option --use-program-dependencies optimiert werden. Besonders in großen Anwendungen mit vielen Abhängigkeiten wie Angular Material ist dies ein entscheidender Faktor.
Neben den spezifischen Konfigurationsoptionen ist es auch wichtig, den gesamten Build-Prozess zu überwachen und zu optimieren. Tools wie der Angular CLI bieten viele integrierte Funktionen, um die Entwicklungsumgebung effizienter zu gestalten. Durch eine durchdachte Implementierung des Angular Compatibility Compilers und seiner Optionen können nicht nur Kompilierungszeiten reduziert, sondern auch die langfristige Wartbarkeit und Performance einer Anwendung verbessert werden.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский