Zum Inhalt springen

Suchen...

Frontend-Testing: Echter Browser statt jsdom

Was bringt ein echter Browser im Frontend-Testing? Vitest Browser Mode prüft Komponenten wie ein Nutzer und zeigt Kontrastfehler, die jsdom übersieht.

• • 7 Min. Lesezeit
Cover zum Expertengespräch über 'Frontend-Testing: Echter Browser statt jsdom' mit Alexander Opalic und Richard Seidl.

Frontend-Testing ist das Prüfen von UI-Komponenten wie Date Picker, Modals oder Tabellen auf Verhalten, Accessibility und Darstellung. Im Vitest Browser Mode läuft jede Komponente isoliert in einem echten Browser, während jsdom und happy-dom den Browser in Node nur emulieren. So lassen sich Farbkontraste automatisch prüfen und Screenshots ganzer UI-Bibliotheken vergleichen, ohne jede Variante von Hand zu suchen.

Das Wichtigste in Kürze

  • Alexander Opalic hält Frontend-Testing für komplizierter als Backend-Testing, weil eine Komponente neben ihrem Verhalten auch Accessibility und Visual Regression als Anforderungen mitbringt.
  • Der Vitest Browser Mode rendert jede Komponente isoliert in einem iFrame eines echten Browsers, während jsdom und happy-dom den Browser in Node nur emulieren und oft Mocks brauchen.
  • Farbkontraste lassen sich mit jsdom nicht automatisch prüfen, im echten Browser fällt grauer Text auf weißem Grund sofort als Accessibility-Problem auf.
  • Ein Klick dauert im echten Browser etwa 200 Millisekunden und mit jsdom etwa 20, eine Testsuite von fünf Minuten braucht damit rund eine halbe Minute länger.
  • Screenshot-Tests lohnen sich für die Core-UI-Library mit allen Button- und Modal-Varianten, für jede einzelne Webseite werden sie dagegen schnell flaky.

Warum Frontend-Testing komplizierter ist als Backend-Testing

Frontend-Testing hat mehr Anforderungen als Backend-Testing, und genau das macht es schwieriger. Alexander Opalic, seit acht Jahren Entwickler und die meiste Zeit davon im Frontend unterwegs, nennt zwei Felder, die im Backend schlicht nicht vorkommen: Accessibility und Visual Regression. Am Ende steht ein Browser, und am Ende stehen irgendwo Pixel. Ein Date-Picker sieht harmlos aus, bringt aber eine lange Liste an Anforderungen mit, sobald er mit einem Screenreader funktionieren soll.

Dazu kommt, wie Tests in vielen Projekten entstehen. Alexander beschreibt den typischen Fall, in dem ein Pull Request 70 Prozent Testabdeckung braucht und die Entwickler diese Zahl irgendwie erfüllen. Die Abdeckung stimmt dann, das Vertrauen in den Code fehlt trotzdem. Seine eigene erste Aufgabe als Werkstudent war genau so ein Auftrag, mehr Testcoverage, noch bevor er wusste, wie man eine Vue-Applikation baut. Es hat lange gedauert und war frustrierend, sagt er heute. Zum Testen gebracht hat es ihn trotzdem.

Was soll ein Test an einer Komponente prüfen?

Das Verhalten, das der Nutzer im DOM sieht. Alexander unterscheidet zwei Arten, denselben Test zu schreiben. Whitebox bedeutet, den inneren Zustand der Komponente zu prüfen, in Vue über ref, in React über useState, dazu ihre einzelnen Methoden. Blackbox bedeutet, die Komponente so zu bedienen, wie ein Nutzer es tun würde, und das Ergebnis im DOM zu prüfen.

„Dem Nutzer ist es egal, welche Methoden eine Komponente hat und welche Namen. Es soll einfach nur funktionieren.“

(Alexander Opalic)

Der Blackbox-Ansatz passt zu der Art, wie Frontends heute gebaut werden. Eine Core-UI-Library liefert Buttons, Modals, Tabellen und Date-Picker, und eine E-Commerce-Seite setzt sich daraus zusammen wie aus Lego-Bausteinen. Jeder dieser Bausteine lässt sich isoliert prüfen. Auf der Teststufe ist das ein Komponententest, also unterhalb der End-to-End-Tests, die mit Playwright die ganze Seite laden. Für einen Date-Picker ist der End-to-End-Weg umständlich, weil der Test erst die richtige Seite ansteuern und das Element dort finden muss.

Was bringt ein echter Browser gegenüber jsdom und happy-dom?

Ein echter Browser zeigt, was jsdom und happy-dom nur nachbilden. Beide Werkzeuge laufen in Node und emulieren einen Browser; das funktioniert für vieles, bleibt aber eine Emulation. Vor drei, vier Jahren haben die meisten Frontend-Entwickler so getestet, und viele Projekte tun es bis heute. Sobald eine Komponente ein Diagramm zeichnet, wird es in Node mühsam, und dann muss ein Mock her. Jedes Mock macht den Test komplizierter und entfernt ihn weiter von dem, was der Nutzer sieht.

Accessibility ist das klarste Beispiel. Ein Bild braucht einen Alt-Text, damit ein Screenreader vorlesen kann, was zu sehen ist. Solche einfachen Regeln prüft axe automatisch. Bei den komplizierteren Dingen hilft der echte Browser, und Farbkontrast gehört dazu. Im Browser fällt sofort auf, wenn graue Schrift auf weißem Hintergrund steht und niemand sie lesen kann. jsdom sieht davon nichts.

Nach Alexanders Erfahrung macht Testschreiben wieder Spaß, sobald man den Browser-Modus einmal ausprobiert hat. Das Problem liegt woanders. Viele Frontend-Entwickler wissen schlicht nicht, dass es ihn gibt.

Wie der Vitest Browser Mode Komponenten rendert

Der Vitest Browser Mode rendert jede Komponente in einem echten Browser und führt ihre Tests dort aus. Vitest ist der Test-Runner im Umfeld von Vite, das Webpack als Build-Werkzeug abgelöst hat, weil es schneller läuft und einfacher zu konfigurieren ist. In der Konfiguration lässt sich je Testdatei eine Umgebung wählen. Für reine TypeScript-Funktionen reicht Node. Für Komponenten heißt die Umgebung Browser.

Dann öffnet Vitest ein iFrame, rendert zum Beispiel den Date-Picker und lässt die fünf oder zehn Tests dieser Komponente laufen. Im nächsten iFrame kommt die nächste Komponente dran, etwa eine Tabelle. Das Ganze sieht Playwright ähnlich, läuft headless oder sichtbar, und mit Timeouts lässt es sich so verlangsamen, dass man jeden Klick mitverfolgen kann. Auf einem Prozessor mit mehreren Kernen laufen vier Komponenten parallel; Vitest verteilt die Tests selbst.

Hinter dem Werkzeug steht VoidZero, die Firma, die Evan You mitgegründet hat. Vite und Vitest gehören dazu, ebenso Oxlint, ein in Rust geschriebener Linter, der schneller läuft als ESLint davor. Den Browser Mode gibt es seit zwei, drei Jahren. Bekannt ist er trotzdem kaum.

Sind Tests im echten Browser langsamer als mit jsdom?

Ja, aber nur wenig. Alexander hat vor kurzem die Tests von Reka UI, einer Headless-Component-Library aus dem Vue-Umfeld, mit KI-Unterstützung von jsdom auf den Browser Mode migriert, vor allem um Zahlen zu bekommen. Ein Klick dauert mit jsdom oder happy-dom rund 20 Millisekunden, im echten Browser können es 200 sein. Eine Suite, die vorher fünf Minuten lief, braucht danach vielleicht fünfeinhalb.

jsdom / happy-domVitest Browser Mode
UmgebungNode, emulierter Browserechter Browser, ein iFrame je Komponente
Ein Klickrund 20 msrund 200 ms
Testsuite Reka UIrund 5 Minutenrund 5:30 Minuten
Diagramme, SliderMocks nötigrendern direkt
Farbkontrastnicht prüfbarsichtbar und prüfbar

Dafür werden die Tests lesbarer. Reka UI musste mit jsdom viel mocken, besonders bei Komponenten wie einem Slider, und diese Mocks fallen weg. Bei der Accessibility kommt der Kontrast als Prüfung dazu, die vorher gar nicht möglich war. Eine halbe Minute mehr Laufzeit gegen weniger Mocks und eine zusätzliche Prüfebene ist ein Tausch, den Alexander gern eingeht.

Teststrategie zuerst, besonders mit KI

Beim Entwickeln mit KI muss die Teststrategie von Anfang an stehen. Alexander hat das an einer eigenen Workout-Tracking-App ausprobiert, die er komplett mit KI gebaut hat. Am Projektanfang hat er Zeit investiert und sich überlegt, was er wie testet.

Der Browser Mode hilft dabei auf einer zweiten Ebene. Die Modelle verstehen Bilder. Schlägt ein Test fehl, sieht der Agent das Bild und versteht leichter, warum.

Flaky Tests, Selektoren und die Grenze der Selbstheilung

Im Browser Mode sind flaky Tests kein größeres Problem als mit Playwright. Das Werkzeug wartet asynchron, bis ein Element da ist, mit einem Timeout als Obergrenze. Probleme entstehen, wenn sich Selektoren ändern. Steht ein Test einmal stabil, bleibt er es. Automatische Retries gibt es, aber ein Test, der wiederholt werden muss, verdient zuerst die Frage, warum.

Alexander hat auch mit Selbstheilung experimentiert. In einer GitHub-Actions-Pipeline kann ein Agent einen geänderten Selektor erkennen, den Test anpassen und den Fix committen. Die Kehrseite: Auf diesem Weg kann der Agent einen echten Fehler wegarbeiten, ohne dass jemand ihn sieht. Darauf solltest du achten, bevor du so eine Pipeline scharf schaltest.

Wann werden Screenshot-Tests flaky?

Visual Regression im echten Browser lohnt sich dort, wo viele Varianten derselben Komponente existieren, und nicht für ganze Seiten. Eine Designerin, die einen Button ändert, soll nicht jede Button-Variante auf der ganzen Website suchen müssen. Mit dem Browser Mode entsteht ein Bild aller Varianten, und bei einer Änderung schlägt der Test an. Ohne so einen Test wird selbst eine kleine Änderung an einem Modal mühsam, weil eine Website schnell 15 bis 20 Modal-Varianten hat und jemand jede davon manuell durchklicken muss.

Für ganze Seiten rät Alexander davon ab, weil dort die Flakiness steigt. Screenshot-Tests gehören an die Core-UI-Library und an wenige sehr wichtige Screens. Den Rest zeigt die Praxis. Wenn ein Regression-Test an einer Stelle ständig fehlschlägt, nimm ihn dort raus.

Ein Werkzeug, das Rückmeldung braucht

Features fehlen Alexander bisher keine. Was fehlt, sind Projekte, die den Browser Mode einsetzen und dabei Wünsche entdecken. Vitest 5 ist vor ein, zwei Monaten erschienen, und der Maintainer hat dazu ein Issue mit der Frage eröffnet, was als Nächstes hinein soll. Dazu gibt es einen Discord. Feedback als Issue ist dort willkommen.

Und dann ist da noch das alte Open-Source-Problem, das Alexander als Frage stehen lässt. Unternehmen benutzen Open-Source-Produkte wie Vite, Vitest oder Oxlint, aber welches gibt als Sponsor etwas zurück?

Diese Seite teilen

Ähnliche Beiträge