Tab-Navigation per JS – nicht nur in automatisierten Unit-Tests

Als ich letztens am Test-Harness einer Angular9-Komponente gearbeitet habe und die Reaktion auf die Tab-Taste automatisiert testen wollte, war ich doch sehr überrascht, dass dies wohl nach wie vor erst in End-2-End-Tests mit Protractor möglich ist, da die Tab-Taste im Unit-Test nicht simuliert wird. Eine Recherche im Netz ergab, dass das wohl nach wie vor als allgemeines Problem angesehen wird und die einzige Bibliothek (jquery-emulatetab) die ich gefunden habe, setzt auf jQuery auf – eine Abhängigkeit, die so gar nicht in den Stack dieses Angular-Projekts hineinpasst. Da habe ich mich gefragt, ob man ein ähnliches Tool nicht ohne größere Abhängigkeiten umsetzen könnte. Nach einer kurzen Evaluations-Phase war klar, dass dies mit wenigen Zeilen Code gelingen könnte und um das Ergebnis vorweg zu greifen, dieses Tool nennt sich nun „emulate-tab“, bedient sich lediglich nativer Browser-Funktionen und ist per npm unter MIT-Lizenz verfügbar.

Die Herausforderungen dabei bestanden zum einen darin, mögliche Tab-Ziele und deren Reihenfolge zu ermitteln. Dabei stützt sich das Tool auf die „tabindex“-Property, die manuell oder vom Browser gesetzt wird. Anschließend werden noch einige Elemente, beispielsweise unsichtbare Eingabefelder aussortiert. Zum anderen müssen alle Events simuliert werden, die der Browser bei einem echten Tastendruck auslösen würde. Angefangen beim „keydown“ über „blur“, „focus“ und „keyup“ bis hin zum selektieren von Inhalten im Zielfeld. Insgesamt stellten sich diese aber als wesentlich unkomplizierter heraus, als im Vorfeld befürchtet. So dass die eigentliche Komplexität im Verifizieren des Verhaltens in unterschiedlichen Testumgebungen bestand.

Die Beispielprojekte in Angular-9 mit Material Komponenten, Typescript und RequireJs und purem HTML mit JavaScript mit entsprechenden jeweils automatisierten Testumgebungen (alle karma/Jasmine) zeigen, dass sich das Tool nicht nur in Angular, sondern auch jeder anderen Testumgebung einsetzen lässt. Im ursprünglichem (wesentlich größeren) Projekt setzte ich auch Jest als Test-Runner ein. Selbst npm ist nicht zwingend erforderlich – das Script lässt sich auch direkt auf der GitHub-Release-Seite herunterladen und so in andere Projekte einbinden.

Nicht nur für Tests – auch bei der Verbesserung der UX auf produktiven Seiten, kann „emulate-tab“ unterstützen. So habe ich beispielsweise einen Fall, in dem ein Button nach dem drücken deaktiviert wird. Das gewollte Verhalten wäre, dass dabei ein beliebiges Feld nach dem Button in den Fokus rückt – das native Verhalten des Browsers selektiert aber das Feld vor dem Button. Da es sich um eine Wiederverwendbare Komponente handelt, ist das Feld nach dem Button nicht bekannt. Durch ein „emulateTab()“ nach dem deaktivieren des Buttons, stellt dies nun keine Herausforderung mehr dar.

Fazit: Das programmatische auslösen einer Tab-Navigation auf Web-Seiten sollte mit „emulate-tab“, einem einfachem kleinen Tool ohne Abhängigkeiten, zukünftig kein größeres Problem mehr darstellen.

RxJS Observables – Everything is a stream

Apache Storm war vor einigen Jahre das Framework, in dem ich mich erstmals mit Streams befasst habe. Damals galt das unter Java mit Storm als innovativ, obwohl es die funktionale Programmierung eigentlich schon seit den 1930er Jahren gibt. Es handelt sich hierbei eben um eine Denkweise, die objektorientierten Entwicklern eher fremd vorkommt. Später war die Implementierung mit Google Guava dann doch etwas handlicher, von der die API ja auch größten Teils in Java 8 übernommen wurde. Dennoch merkt man stark, dass Java ursprünglich nicht als funktionale Programmiersprache gedacht war.

RxJS Observables, auf das ich dank Angular 2 gestoßen bin, ist anders – einmal damit angefangen, tendiert man dazu nichts mehr auf konventionelle, rein objektorientierte Art und Weise umzusetzen. Die Herausforderung liegt nun darin, gerade bei funktionaler Implementierung lesbaren CleanCode zu schreiben. Gerade hier ist das besonders wichtig, da es mit Lambda-Ausdrücken sehr verlockend ist, den Code so weit zu kürzen, dass er absolut unverständlich wird. Im besten Fall verbringt man dann selbst Stunden damit zu verstehen, was man da mal getan hat – im schlimmsten Fall muss sich ein Kollege durchkämpfen, der dringend einen Fehler beheben soll und bis dato noch wenig bis keine Kontakte mit funktionaler Programmierung hatte.

Als Schnellstart kann ich in so einem Fall nur „The introduction to Reactive Programming you’ve been missing“ von andrestalz empfehlen, befürchte aber, dass die Umstellung der Denkweise ohne echtes Training eine Mammutaufgabe sein könnte.

Contributed to Angular 2

Merged! Zugegeben, es waren nur Code-Beispiele, wobei ich diese, besonders bei einem Framework für außerordentlich wichtig halte. Ich muss sagen, es ist ein gutes Gefühl an einem Projekt wie Angular mitwirken zu können. Jedenfalls war es eine interessante Erfahrung eine neue Perspektive auf das Projekt kennen zu lernen.

Technisch gab es natürlich einige interessante Punkte:

  • Anlegen eines lokalen Angular 2 Workspaces, in dem die einzelnen Module per Script durch symbolische Verknüpfungen verbunden werden.
  • Der Build-Process über Shell- und Gulp-Scripts
  • Die Quality-Gates über Linting und Tests

Menschlich fand ich es noch interessanter, da ich positiv überrascht war, wie freundlich, offen und hilfsbereit das Team reagiert hat. Und auch wenn die Zeitverschiebung die Kommunikation leicht erschwerte, bekam ich schnell Optimierungsvorschläge, die konstruktiv diskutiert wurden – ein beispielhaft gut geleberter GIT-Prozess eben.

Fazit: Ich konnte einen wesentlich tieferen Einblick in Angular 2 gewinnen und hatte Spaß dabei. Deshalb hoffe ich, dass ich zukünftig öfter oder gar regelmäßig Zeit finde an solchen Projekten mitzuarbeiten.

Jasmine – so dokumentiert man heute

Was ist Jasmine? Offensichtlich ein Test-Framework für JavaScript-Code. Aber schon in der Einführung zeigt es anschaulich, dass es vor allem auch zur Dokumentation von Software genutzt werden sollte.

Grundsätzlich bin ich, als ein Verfechter von CleanCode, ja der Meinung: Dokumentation von Implementierungsdetails sollte nicht notwendig sein, da der Code selbst so gestaltet werden sollte, dass man keine zusätzlichen Kommentare und Beschreibungen benötigt.

Die Herausforderung zusätzlicher Dokumentation von Softwaredetails (wenn denn mal vorhanden) liegt im Allgemeinen ja darin, diese aktuell und verlässlich zu halten. Sobald ich von der Dokumentation in den Quellcode wechseln muss, um zu prüfen ob die Beschreibung noch aktuell ist, wir diese schnell wertlos. Jasmine ist ein Framework mit dem man sehr schnell seine Dokumentation verfassen kann und zugleich die entsprechenden Testfälle integriert, die beweisen, dass die Software auch genau so arbeitet wie es beschrieben ist. Dazu macht es einem die sprechende API von Jasmine sehr einfach, auch die Umsetzung der Beweise lesbar zu gestalten – ein überzeugendes Beispiel hierzu liefert die eingangs erwähnte Einführung.

Fazit: Neben der Tatsache, dass es Spaß macht ein neues Projekt mit dem schreiben eines Jasmine-Tests zu beginnen, ist die Einführung von Jasmine ein herausragendes Beispiel wie man lesbaren Code gestalten kann.

Angular 2.0 – Erstkontakt

Aufbruch in eine neue Welt! Meine viermonatige Elternzeit verging wie im Flug und schon steht die nächste Herausforderung an: neues Projekt, komplett neuer Technologie-Stack. Nachdem ich drei viel zu lange Jahre mit der Architektur eines Softwaregiganten auf Basis von Java 1.6, Oracle SQL, Vaadin 7, jUnit, Mockito, Tomcat und Maven verbracht habe, steht jetzt das Kontrastprogramm mit TypeScript, MongoDB, Angular 2.0, Jasmine, nginx, npm und VisualStudioCode auf dem Plan.

Tour of Heroes titelt das erstklassige Einführungs-Tutorial von Angular. Schade, dass man in der Praxis selten die Zeit findet sich so systematisch in ein neues Thema einzuarbeiten. Ich hatte das Glück nicht nur die „Tour of Heroes“ komplett durchgehen, sondern mir darüber hinaus weitere Themenschwerpunkte wie die Architekturkonzepte, Reactive Forms, Pipes, Routing und vor allem Testing ansehen zu können. Letzteres wäre auch einer der einzigen beiden Kritikpunkte, die sich an der Tour finden lassen (der andere ist die Aufteilung – während die ersten Kapitel in Minuten zu bewältigen sind, brauchen die letzten Tage): ich bin ein großer Fan von TestDrivenDevelopement und habe mich deshalb sehr unwohl gefühlt, die Einführung ohne einen einzigen Test zu starten und bin schnell dazu übergegangen das Kapitel „Testing“ parallel zu bearbeiten. Das ist nicht immer ganz einfach gewesen, hat mir aber einen wesentlich tieferen Einblick in das Framework gegeben.

Fazit: Angular 2.0 hat bei mir einen sehr positiven ersten Eindruck hinterlassen – kein Wunder, dass es inzwischen so weit verbreitet ist. Die Basics sind sehr schnell zu erlernen, man sollte sich aber parallel unbedingt die Tests mit ansehen und es lohnt sich tiefer in die Konzepte zu gucken.

Hello World!

code better than last week – jede Woche nehme ich mir Zeit, mich selbst weiterzuentwickeln. Diese Woche musste ich mich mal wieder um eine eigene Homepage kümmern – ihr kennt das mit den Schustern und den schlechtesten Schuhen. Wie ihr hier sehen könnt, ist meine Wahl auf WordPress gefallen.

Wieso WordPress? Natürlich ist das nicht mein erster Anlauf. Irgendwann gab es da mal eine PHP-Seite, als ich mir vor Jahren Java Server Faces 2.0 angesehen habe, habe ich eine JSF-Seite angefangen und als ich mich in Vaadin eingearbeitet habe, habe ich eine Vaadin-Seite. Dabei entstanden viele einzelne Seiten, aber was fehlte war die Klammer, der Rahmen der alles zusammenhält. Was muss mein Rahmensystem also können? Zunächst einmal sollte es weit genug verbreitet sein, um eine gewisse Stabilität und Sicherheit zu gewährleisten – ich kann nicht alle paar Wochen ein neues Grundsystem aufsetzen, meine Internetseite muss einfach laufen. Dann muss es einfach zu pflegen sein – muss ich mir erst überlegen, wann ich dazu Zeit finde Inhalte anzupassen, mache ich es nie. Nicht zuletzt muss es flexibel erweiterbar sein – schließlich geht es um Softwareentwicklung und hierzu werde ich sicher das ein oder andere interaktive Beispiel einbinden wollen. Ach so … und repräsentativ Aussehen wäre vielleicht auch nicht schlecht. Spätestens wenn man den Punkt „Stabilität und Verbreitung“ mit in die Auswahlkriterien für sein Content-Management-System nimmt, fällt die Entscheidung nicht mehr sonderlich schwer: Hallo WordPress!

Aber WordPress ohne Blog? Ja, sicher, mit WordPress kann man, nicht zuletzt dank der unzähligen Plugins, inzwischen weit mehr machen als „nur“ zu bloggen. Nur jetzt, wo es schon mal läuft, muss ich das mit dem Bloggen auch mal probieren, und da du hier unten ankommen bist: Hallo Leser!