eurofunk Kappacher GmbH
Cypress Component Tests
Description
Patrick Pichler von eurofunk Kappacher demonstriert in seinem devjobs.at TechTalk die Herangehensweise des Teams, wie sie Component Tests mit cypress durchführen.
Beim Videoaufruf stimmst Du der Datenübermittlung an YouTube und der Datenschutzerklärung zu.
Video Zusammenfassung
In "Cypress Component Tests" zeigt Patrick Pichler (eurofunk Kappacher GmbH), wie Cypress’ Component Testing die Lücke zwischen Unit- und End-to-End-Tests schließt—nachdem Angular-Unit-Tests (Konfiguration, DOM-Interaktion, Asynchronität, Change Detection, HTTP‑Mocks) mühsam waren und E2E/Storybook‑Setups langsam und aufwendig. Er demonstriert am Login-Beispiel den Runner und Techniken wie Mounten von Komponenten mit Providern, Custom Commands, Inputs (inkl. Signals) und Outputs (CreateOutputSpy), Template-basiertes Zusammenspiel, DI-Zugriff sowie Netzwerkmocking via cy.intercept. Ergebnis: eine vereinfachte CI (nur Cypress), in der rund 259 Tests in ca. drei Minuten laufen und lokal in Sekunden Feedback liefern—eine praxisnahe Blaupause, um Frontend‑Komponenten schneller und zuverlässiger zu testen.
Cypress Component Tests mit Angular: Wie Patrick Pichler (eurofunk Kappacher GmbH) die Lücke zwischen Unit und E2E-Tests schließt
Kontext: Hohe Qualitätsansprüche treffen auf reale Testschmerzen
In „Cypress Component Tests“ zeigt Patrick Pichler von eurofunk Kappacher GmbH, wie sein Team den Test-Stack im Frontend neu ausbalanciert. Pichler ist seit 17 Jahren in der Softwareentwicklung, fokussiert auf Frontend, und arbeitet an der EOX (Eurofunk Operations Center Suite). eurofunk Kappacher GmbH liefert komplette Leitstellenlösungen – von Möbeln über Server und Verkabelung bis hin zur Software, inklusive Multimedia-Integration und Videowänden. In der Produktentwicklung arbeitet Pichler im Bereich „Products Foundation“, der Plattformlösungen baut, damit Stream-aligned Teams Features schneller liefern können.
Vor diesem Hintergrund ist Testqualität kein Luxus. Sie entscheidet pragmatisch über Arbeitsgeschwindigkeit und Zuverlässigkeit. Die Testpyramide liefert zwar die bekannte Richtung – viele Unit-Tests, weniger Integrationstests, wenige End-to-End-Tests –, aber die gelebte Realität in Pichlers Bereich sah anders aus: viele Unit-Tests, fast keine Integrationstests und sehr viele End-to-End-Tests mit Cypress. Das war kein bewusstes Ziel, sondern „ist einfach passiert“ – getrieben vom Tech-Stack (Angular) und den Stolpersteinen im klassischen Komponententesten.
Wo klassische Angular-Tests weh tun
Pichler benennt fünf Schmerzfelder, die in Angular-Unittests immer wieder produktiv stören: Testkonfiguration, DOM-Interaktion, Asynchronität, Change Detection (Synchronisation) und HTTP-Mocks.
1) Testkonfiguration
- Verstehen des Angular-Modulsystems macht das Setup schwergewichtiger. Neuere Angular-Versionen mit „standalone“ entschärfen das, aber die Hürde bleibt spürbar.
- Alle Abhängigkeiten müssen testseitig korrekt bereitgestellt werden. Man muss wissen, wie die Komponente in der App verkabelt ist, und das im Testbett replizieren.
- Strategiefrage: Was mocke ich? Alles? Nur Services? Angular-Core-Features wie Routing oder HTTP müssen oft explizit gemockt werden.
2) DOM-Interaktion
- Banale Checks erzeugen überraschend viel Boilerplate. Ein einfacher Zugriff auf ein P-Tag und dessen Textinhalt ist nicht schwer – aber umständlich.
- Inputs und reaktive Elemente verlangen die präzise Simulation nativer Browserverhalten. Wer hier die falschen Events triggert, testet am Nutzer vorbei. Das ist kein Angular-spezifisches Problem und trifft insbesondere Einsteigerinnen und Einsteiger.
3) Asynchronität
- „Asynchrony is just hard in general.“ Die Unterscheidung und richtige Nutzung von
fakeAsyncundasyncist nicht trivial. tickundflushinfakeAsyncsind erklärungsbedürftig; Fehlerbilder sind oft Timing-getrieben und damit schwer zu debuggen.zone.jspatcht Funktionen wiesetTimeoutundsetInterval. Reinesasync/awaitkann an Angulars Mechanik vorbei arbeiten – mit überraschenden Effekten.
4) Change Detection (Synchronisation)
- Im Test muss Change Detection teilweise manuell getriggert werden, anders als im echten App-Laufzeitverhalten.
- In Kombination mit Asynchronität entstehen Timing-Fallen.
- Die Strategie
OnPushsteigert die Komplexität noch einmal.
5) HTTP-Mocks
- Der
HttpTestingControllerfügt Komplexität hinzu, die man erst erlernen muss. - Wieder kommen Asynchronität, Change Detection und HTTP zusammen – ein Dreiklang, der in Summe fehleranfällig ist.
- Fehlerfälle zu mocken ist weniger „straightforward“ als die API vermuten lässt.
Kurz: All das drückt die Ergonomie und verlagert Tests im Zweifel nach oben in E2E-Szenarien – genau das, was die Testpyramide vermeiden will.
E2E mit Cypress: stark – aber teuer im Durchlauf
eurofunk Kappacher GmbH setzt im End-to-End-Bereich auf Cypress. Der bekannte Runner zeigt Testschritte links und rendert rechts die echte Anwendung. Pichler spricht von „rund 1.000“ E2E-Tests (als Daumenzahl per Dateisuche ermittelt) – nicht nur in seinem Projekt, auch in anderen Teams.
Mit so viel Cypress-Know-how lag ein naheliegender Gedanke auf dem Tisch: Können wir Cypress gegen isolierte Komponenten laufen lassen und so Frontend-Integrationstests beschleunigen? Der erste Ansatz kombinierte Cypress mit Storybook.
Storybook + Cypress: theoretisch gut, praktisch zu langsam
Die Pipeline sah so aus:
- Storybook bauen (Artefakte erzeugen)
- Node-basierte HTTP-Serverinstanz starten, die die Storybook-Artefakte ausliefert
- Cypress bauen (Tests bündeln)
- Cypress-Tests gegen den lokalen Server ausführen
Das funktionierte – aber lief in der Praxis „10+ Minuten“ selbst für wenige Tests. Zwei Build-Prozesse, ein zusätzlicher HTTP-Server und Storybook (damals Version 6) bremsten die Feedbackschleife deutlich aus. Für schnelle Iteration ist das zu träge.
Allgemeine E2E-Schmerzpunkte
Pichler fasst die bekannten Nachteile von End-to-End-Tests zusammen:
- Sie sind langsamer als Unit- oder Integrationstests. Nutzerinteraktionen und Reaktivität erzwingen Wartezeiten.
- Längere Feedbackzyklen verlangsamen die Entwicklung. In seinem Umfeld laufen E2E-Tests nicht als Teil jeder CI-Ausführung, sondern mehrmals täglich zeitgesteuert – das Feedback kommt oft Stunden nach dem Deployment, inklusive Kontextwechselkosten.
- Flakiness unterminiert Vertrauen. Netzwerkrandbedingungen und Umgebungsfaktoren lassen Tests sporadisch kippen.
- Komplexes Setup und Debugging. Man debuggt eher eine Mini-Produktionslandschaft als eine isolierte Komponente.
- Infrastrukturkosten und realistische Testdatenverwaltung sind echte Aufwände.
Genau hier positioniert Pichler Cypress Component Testing als passenden Mittelweg.
Cypress Component Testing: Isolation mit realer DOM-Interaktion
Cypress Component Testing sitzt zwischen Unit- und E2E-Tests. Unterstützte Frameworks sind React, Angular, Vue und Svelte (Stand zum Zeitpunkt des Vortrags). Der Ansatz: Komponenten isoliert mounten, über die echte DOM-Schicht mit ihnen interagieren und Cypress die Asynchronität abnehmen lassen.
Vorteile aus der Praxis
- Komponenten laufen isoliert – mit der Präzision und Kontrolle von Unit-Tests.
- Keine manuelle Asynchronitätsverwaltung: Cypress übernimmt das „Warten“, wie bei E2E.
- Keine manuelle Change Detection: Die Komponente verhält sich „wie in der App“ und nicht wie in einer künstlichen Testhülle.
- Starke Developer Experience: Der visuelle Runner zeigt Schritte, Zustände, Screenshots und bei Bedarf CI-Videos.
- Tempo: Ohne Backend-Setup und ohne Storybook/Server ist die Schleife deutlich schneller.
„Der Developer Experience ist großartig … und natürlich ist die Geschwindigkeit erhöht.“
Grenzen und Trade-offs
- Testkonfiguration bleibt notwendig: Wer eine Komponente mountet, muss ihre Abhängigkeiten kennen und bereitstellen.
- Zeitkontrolle: Die Übernahme der Uhr durch Cypress steht derzeit im Konflikt mit Change-Detection-Algorithmen in Angular und React. Ein offenes Bug-Ticket existiert.
- Tests ohne DOM-Interaktion machen wenig Sinn in einem UI-orientierten Framework.
Pipeline nach der Migration: ein Kommando, Minuten statt Zehn-Minuten-Blöcke
Pichlers Team strich die Storybook- und HTTP-Server-Schritte komplett. Die neue CI-Pipeline: Cypress als einziger Schritt, der buildet und testet.
- Beispielprojekt mit 259 Tests: etwa 3 Minuten Laufzeit in CI (inklusive Kompilierung und Testausführung).
- Lokal: Einmalige Kompilierung, dann Watcher; kompletter Lauf in etwa 1 Minute.
- Während der Entwicklung: Fokus auf einzelne Tests mit Laufzeiten „in Sekunden“.
- Zielvorgabe: Feedback unter 5 Minuten pro Pipeline-Job – wird erfüllt.
Für die Product-Foundation-Rolle bedeutet das: schnellere, häufigere Rückmeldungen und weniger Reibung im Tagesgeschäft.
Die Demo: Login-Formular, Komponenten-Mount und Debug-Erlebnis
Zur Veranschaulichung nutzte Pichler ein Login-Formular („GooseCorp“) mit Live-Validierung und einem zeitverzögerten Login-Ergebnis (Banner nach einigen Sekunden).
Cypress-Runner und Browserwahl
Beim Start trennt Cypress klar zwischen End-to-End und Component Tests. Entwicklerinnen und Entwickler können den Zielbrowser auswählen, etwa Chrome, und somit Verhalten und Styling in verschiedenen Browsern gegentesten.
Sichtbarkeit der Testschritte
Der Runner zeigt links die Testschritte und rechts die gerenderte Komponente. Besonders wertvoll: das Debugging.
- Schritte können einzeln geöffnet werden; Cypress hebt die getroffenen DOM-Elemente im rechten Panel hervor.
- Pinning eines Elements ermöglicht das genaue Inspizieren in den DevTools – inklusive Anzahl gefundener Elemente und Metadaten.
- Bei Interaktionen zeigt Cypress koordinatengenau, wo geklickt wurde, und stellt sicher, dass das Element wirklich klickbar ist (sichtbar, nicht überlagert). Andernfalls bricht Cypress mit einer klaren Fehlermeldung ab.
„Cypress prüft, ob ein Element überhaupt klickbar ist … und wirft einen Fehler, wenn die Koordinaten kein Klick-Event erzeugen würden.“
Teststruktur und Mounting: vertraute Syntax, gezielte Provider
Cypress Component Tests nutzen gewohnte Test-Semantik: describe, beforeEach, it. Zentrales Element ist das Mounten der Komponente. Hier liegt der Rest an notwendiger Testkonfiguration.
- Im Beispiel mountet Pichler die Login-Komponente und liefert die benötigten Provider mit – u. a. eine Animationskonfiguration sowie eine interne Icon-Bibliothek über
provideIcons. - DOM-Zugriffe erfolgen via
cy.getmit jQuery-ähnlicher Syntax. Assertions wiebe.visiblesind direkt verfügbar, inklusive Autovervollständigung. typesimuliert echte Nutzereingaben Zeichen für Zeichen und triggert alle relevanten Browser-Events.clickinteragiert robust und prüft die Klickbarkeit.
Dieses Setup reduziert die kognitive Last: statt Event-Simulationen und Change-Detection-Hilfen sind Mounting und Interaktion im Vordergrund.
Komfortschicht: Custom Commands für Mounting und Selektoren
Damit Testfälle noch kompakter werden, setzt Pichlers Team Custom Commands ein:
- Ein eigenes
mount-Kommando liefert immer die Default-Provider mit, etwa Animationen und die Icon-Bibliothek. Jede Komponente profitiert davon, ohne dass Testautorinnen und -autoren Boilerplate wiederholen. - Ein
getByQA-Kommando kapselt den Zugriff überdata-qa-Attribute, sodass Selektoren stabil und lesbar bleiben.
Das Ergebnis: weniger Rauschen im Testcode, klarer Fokus auf das Verhalten.
Inputs, Live-Updates und Outputs: Komponente wie in der App ansteuern
Inputs beim Mounten
Über „component properties“ im Mounting-Call lassen sich Eingaben direkt setzen, z. B. eine benutzerdefinierte Info-Nachricht, die statt der Standardmeldung angezeigt wird.
Live-Updates mit Signals
Um Eingaben nach dem Mounten zu verändern, nutzt Pichler Signals. Ein Signal wird erstellt, als Input gebunden und später auf einen neuen Wert gesetzt. Change Detection und UI-Update passieren automatisch – genau das gewünschte Verhalten für dynamische Testszenarien. Details zu Signals vertieft Pichler im Talk nicht; hier bleibt der Fokus auf der praktischen Verwendbarkeit im Testlauf.
Outputs mit CreateOutputSpy
Events der Komponente (Outputs) werden über CreateOutputSpy verifiziert. Beispiel: Ein Output afterLogin wird mit einem Spy hinterlegt, der später über ein Alias adressiert und mit bekannten Mustern geprüft wird – etwa „wurde das Event genau einmal ausgelöst?“ oder „kam der erwartete Parameter an?“. Die Syntax entspricht dem, was viele bereits aus Unit-Testing kennen.
Integration auf Komponentenebene: Template-Syntax für zusammenspielende Bausteine
Nicht jede Frage lässt sich an einer Single-Komponente beantworten. Für typische Kombinationen – Pichler nennt z. B. ein Akkordeon mit Panels – bietet Cypress Component Testing die Möglichkeit, über eine Template-String-Syntax mehrere Komponenten zusammenzusetzen. Inputs und Outputs werden wie in Angular üblich gebunden.
Wichtiges Detail: Die componentProperties beziehen sich dann auf eine generische Host-Komponente. Es ist sinnvoll, eine Interface-Definition zu pflegen, die alle gebundenen Inputs und Spies abbildet, etwa infoMessage und afterLoginSpy. So bleiben die Tests typsicher und nachvollziehbar.
Zugriff auf Instanzen und DI: Fixture, Injector und Component Instance
Nach dem Mounten stellt Cypress einen Wrapper bereit, der u. a. eine fixture enthält. Darüber lässt sich der Angular-Injektor abrufen, um Services zu beziehen, Spies zu setzen oder Interaktionen auszulösen. Zusätzlich ist die eigentliche Komponenteninstanz zugreifbar, wenn etwa statische Eigenschaften oder interne Zustände verifiziert werden sollen. Pichler zeigt den Injector-Weg exemplarisch; der direkte Zugriff auf die Komponenteneigenschaft ist ebenfalls Teil des Wrappers.
HTTP-Mocking: drei Wege – einer ist meist der richtige
Komponenten werden früher oder später Netzwerkaufrufe auslösen. Im Test will man das vermeiden – schon aus Stabilitäts- und Geschwindigkeitsgründen.
Pichler demonstriert drei Herangehensweisen:
- Service überschreiben: Den aufrufenden Service durch ein Mock ersetzen und Testdaten zurückgeben. Einfach und effektiv.
- Angulars
HttpTestingControllerverwenden: ÜberprovideHttpTestingClienteinrichten, Requests abfangen und Antworten „flushen“. Möglich und lehrreich, aber in diesem Kontext nicht die bevorzugte Lösung. - Cypress
interceptnutzen: URL-Muster definieren, Antwort stubben, optional ein Alias vergeben und mitwaitauf den Request warten. Danach Assertions gegen das UI vornehmen. In Pichlers Worten ist dies „wahrscheinlich der richtige Weg“ für diesen Anwendungsfall.
Der dritte Weg harmoniert am besten mit der Cypress-Philosophie: echte DOM-Interaktion, Cypress-gesteuertes Timing und klare, sichtbare Effekte in der Oberfläche.
Warum das alles wichtig ist: Geschwindigkeit, Vertrauen, Fokus
Die Kernbotschaft aus Pichlers Erfahrungsbericht:
- Mit Cypress Component Testing lässt sich die Testpyramide in der Praxis wieder strukturieren. Isolierte, schnelle Tests fangen viele Fälle ab, die sonst in E2E landen würden.
- Cypress übernimmt die raue Kante von Asynchronität und Interaktions-Details. Entwicklerinnen und Entwickler konzentrieren sich auf Verhalten, nicht auf Event- oder Change-Detection-Handwerk.
- Die Pipeline wird schlanker und liefert in Minuten Feedback. Das passt zu realen Zielen im CI/CD („unter 5 Minuten pro Job“).
- E2E bleibt wichtig – aber nicht als Default für alles, was die Komponente betrifft. Flakiness, Infrastrukturkosten und Debug-Aufwand sollten für die „richtigen“ Szenarien aufgehoben werden.
„Cypress Component Tests sind ein großartiges Werkzeug, um die Lücke zwischen End-to-End und Unit zu füllen.“
Konkrete Takeaways für Angular-Teams
- Behalte die Testkonfiguration im Griff. Ein dediziertes
mount-Custom-Command mit Default-Providern spart auf Dauer enorm Zeit und Nerven. - Nutze
data-qa-Attribute und eingetByQA-Kommando, um robuste Selektoren zu etablieren. - Simuliere Nutzerverhalten über Cypress-Kommandos wie
typeundclick. Vertraue auf die integrierten Checks (z. B. „klickbar“), statt eigene Heuristiken zu basteln. - Binde Inputs beim Mounten und nutze
Signalsfür Live-Updates. So testest du dynamische UIs realitätsnah, ohne manuelle Change Detection. - Verifiziere Outputs mit
CreateOutputSpy. Das fühlt sich an wie Unit-Testing – nur mit echter DOM-Oberfläche. - Für zusammenspielende Komponenten setze auf die Template-Syntax und kapsle die Bindungen in ein Host-Interface.
- Wenn HTTP ins Spiel kommt, beginne mit
intercept. Überschreibe Services, wenn es die Architektur nahelegt; greife zumHttpTestingControllernur, wenn du einen triftigen Grund hast. - Plane E2E-Tests dort, wo Systemintegration, Netz und reale Infrastruktur zählen. Für Komponentenlogik und Interaktion ist Component Testing die effizientere erste Wahl.
Fazit
Patrick Pichler zeigt, wie Cypress Component Testing in einem Angular-Setup praktische Bremsklötze entfernt: weniger Boilerplate, weniger manuelle Asynchronität, weniger Change-Detection-Tricks – dafür mehr echte Interaktion, Sichtbarkeit und Geschwindigkeit. Die Migration weg von Storybook-getriebenen Tests hin zu reinem Cypress Component Testing verschlankt die Pipeline auf „ein Kommando“ und drückt die Laufzeiten von „10+ Minuten“ auf wenige Minuten für hunderte Tests.
Für Teams, die – wie bei eurofunk Kappacher GmbH – hochwertige Frontends unter realen Randbedingungen liefern müssen, ist das ein überzeugender Hebel. Die Testpyramide wird wieder zur Leitlinie: Unit- und Komponententests fangen den Großteil ab, E2E deckt die Integrationsspitzen ab. Ergebnis: schnellere Feedbackschleifen, höhere Teststabilität und mehr Vertrauen in das, was wirklich zählt – die Qualität des ausgelieferten Verhaltens.
Weitere Tech Talks
eurofunk Kappacher GmbH From Sound to Sense
Sabine Hasenleithner von eurofunk Kappacher spricht in ihrem devjobs.at TechTalk über die technischen Hintergründe von Sprach Erkennung im Notruf Kontext und zeigt in einer Live Demo eine mögliche Implementierung.
Jetzt anseheneurofunk Kappacher GmbH Effortless Versioning
Stefan Höller von eurofunk Kappacher zeigt in seinem devjobs.at TechTalk, wie das Unternehmen die Versionsverwaltung bei langen Produktzyklen mithilfe von Semantic Release gestaltet hat.
Jetzt anseheneurofunk Kappacher GmbH Application Load Testing with k6
Daniel Knittl-Frank von eurofunk Kappacher spricht in seinem devjobs.at TechTalk darüber, wie die hohen Performance Anforderungen der im Unternehmen entwickelten Software erfüllt werden.
Jetzt ansehen
Weitere Tech Lead Stories
eurofunk Kappacher GmbH Thomas Ronacher, Head of Technical Support bei eurofunk Kappacher
Thomas Ronacher von eurofunk Kappacher spricht im Interview über die Struktur des Teams, die verwendeten Technologien und wie der Bewerbungs- und Onboardingprozess abläuft.
Jetzt anseheneurofunk Kappacher GmbH Johanna Blum, Release Train Engineer bei eurofunk Kappacher
Johanna Blum von eurofunk Kappacher beleuchtet im Interview die Teamkultur, die wichtigsten Technologien im Einsatz und die Besonderheiten des Recruiting-Prozesses.
Jetzt ansehen
Weitere Dev Stories
eurofunk Kappacher GmbH Viktoria Haselsteiner, Scrum Master bei eurofunk Kappacher
Viktoria Haselsteiner von eurofunk Kappacher spricht im Interview über ihren Einstieg in die Welt von Scrum, welche Fähigkeiten sie dabei als besonders hilfreich erlebt hat und worauf es ihrer Meinung nach in der täglichen Arbeit wirklich ankommt.
Jetzt anseheneurofunk Kappacher GmbH Maximilian Spiesmaier, IT Security Consultant bei eurofunk Kappacher
Maximilian Spiesmaier von eurofunk Kappacher teilt im Interview seine Erfahrungen aus der IT Security, welche Herausforderungen er im Arbeitsalltag meistert und wie man am besten in den Beruf startet.
Jetzt anseheneurofunk Kappacher GmbH Valentin Zintl, Junior Development Engineer bei eurofunk Kappacher
Valentin Zintl von eurofunk Kappacher erzählt im Interview über seinen Karriereweg, welche Aufgaben ihn täglich erwarten und welche Fähigkeiten besonders für den Einstieg wichtig sind.
Jetzt anseheneurofunk Kappacher GmbH Johannes Festi, Trainee Software Development bei eurofunk Kappacher
Johannes Festi von eurofunk Kappacher gibt im Interview Einblicke in den Arbeitsalltag als Software Development Trainee, wie er dazu gekommen ist und was seiner Ansicht nach wichtig für den Einstieg ist.
Jetzt ansehen