Frontend-Testing: Statisches Testen vs Unit-Tests vs Integrationstests vs E2E-Tests
Mateusz Wójcik
20. Juli 2020・5 Min. Lesezeit
Inhaltsverzeichnis
Was ist statisches Testen?
Statisches Testen mit ESLint
Statisches Testen mit TypeScript
Frontend: Unit-Tests
Frontend-Testing: Integrationstests
Frontend-Testing: End-to-End-Tests
Zum Schluss: Frontend-Testing
Frontend-Testing ist ein wesentlicher Teil der Entwicklung. Die Vorteile, Tests in unsere Apps einzubauen, liegen auf der Hand, dennoch kann das Thema verwirrend sein. Es gibt viele Testarten, und ihre Definitionen variieren je nachdem, wen man fragt, welche Tools man nutzt und wie man Code testet. Im Internet finden sich verschiedene „Roadmaps“ fürs Frontend-Testing, etwa die testing pyramid oder das testing dorito. Aber die Testing Trophy von Kent C. Dodds hat mich besonders angesprochen. Gehen wir die einzelnen Segmente dieser Trophäe durch und schauen uns ihre Vor- und Nachteile an.
Was ist statisches Testen?
Statische Tests sollten die Basis des Frontend-Testings bilden. Dazu gehören Linter (z. B. ESLint) und statische Typprüfung (z. B. TypeScript).
Statisches Testen mit ESLint
ESLint ist im JavaScript-Ökosystem sehr verbreitet. Das Tool scannt den Code und findet potenzielle Probleme, etwa wenn eine Variable verwendet wird, die noch nicht deklariert ist, oder wenn eine Funktion genutzt wird, die gar nicht importiert wurde. Einige dieser Probleme kann ESLint automatisch beheben. Die Einrichtung ist einfach, und es gibt fertige Konfigurationen, um schnell loszulegen, etwa eslint:recommended oder eslint-config-react-app.
Die notwendigen Pakete sind in wenigen Minuten installiert. Sinnvoll ist es, die IDE so zu konfigurieren, dass ESLint bei jedem Speichern läuft, oder Tools wie Husky und Lint-Staged zu verwenden, um ESLint bei jedem Commit auszuführen. So wird sichergestellt, dass jeder Code, der in ein Remote-Repository gelangt, geprüft und idealerweise von ESLint behoben wird.
Statisches Testen mit TypeScript
TypeScript erfordert etwas mehr Aufwand. Es ist ein Superset von JavaScript und erweitert dessen Möglichkeiten, vor allem um statische Typprüfung, die viele Programmiersprachen bieten, JavaScript jedoch nicht.
Damit lässt sich der Typ von Variablen oder Funktionsparametern festlegen. Zum Beispiel in der Funktion function
sum(a: number, b: number): number { return a + b; }geben wir an, dass die Parameter „a“ und „b“ Zahlen sein sollen und dass unsere Funktion eine Zahl zurückgibt.
Versucht man nun, einen String als Argument zu übergeben, fängt TypeScript den Fehler ab. Der Einsatz von TypeScript ist der anspruchsvollste Teil des statischen Testens, weil Entwickler dafür neue Syntax lernen müssen.
Frontend: Unit-Tests
Unit-Tests sind recht einfach, weil sie isolierte Teile der App prüfen. Keine externen Abhängigkeiten, keine zusätzlichen Frameworks.
Sie können sogar nur eine einzelne Funktion testen. Für die Funktion „sum“ könnte ein Unit-Test so aussehen:
test('sum function', () => { expect(sum(1, 3)).toBe(4); });In diesem Test erwarten wir, dass die Summe von 1 und 3 gleich 4 ist.
Unit-Tests sind leicht lesbar – fast wie normales Englisch: „Erwarte, dass sum mit den Argumenten 1 und 3 das Ergebnis 4 liefert.“ In der Testing Trophy sind sie ein guter Einstiegspunkt für komplexere Tests. Wer sich dafür interessiert, sollte sich die Jest-Bibliothek ansehen. Sie benötigt wenig Konfiguration und funktioniert in der Regel hervorragend, sofern genügend Helper vorhanden sind, um alles Nötige zu testen. Außerdem lassen sich komplexere Fälle mit Mocking von API-Requests und -Responses abdecken.
Im Produktentwicklungsprozess sollte man sich auf die geschäftskritischen Teile der Anwendung und deren Logik konzentrieren. Andernfalls testet man schnell Implementierungsdetails – und das ist unnötig. Bisher ist euer Code durch statische Tests abgedeckt, und einige Teile der App haben eigene Unit-Tests. Schauen wir uns als Nächstes die Integration an.
Frontend-Testing: Integrationstests
Integrationstests stellen sicher, dass verschiedene Teile der App zusammen funktionieren. Aus Business-Sicht sind sie besonders wichtig. Nutzern ist egal, ob eine einzelne Funktion läuft – sie wollen die gesamte Anwendung nutzen können. Genau hier glänzen Integrationstests.
Die React Testing Library ist ein Go-to-Tool für Integrationstests. Ihr Ziel ist es, so zu testen, wie Nutzer die App tatsächlich verwenden, und Implementierungsdetails zu vermeiden. RTL bietet viele Utilities, die Tests einfacher und wartbarer machen.
Betrachten wir eine einfache React-Komponente. Sie besteht aus einem Label, das über die Eigenschaft „htmlFor“ mit einem Input-Feld verbunden ist, einem Button zum Anzeigen einer Nachricht und einem Absatz-Element, das die Nachricht darstellt. Der Button hat einen onClick-Handler, der den Nachrichten-Status ändert.
Diese einfache Komponente hat also ein Label mit zugehörigem Input, einen Button zum Anzeigen der Nachricht und einen Paragraph, in dem sie dargestellt wird.
Fügen wir nun einen Test hinzu: Wir rendern die Komponente, wählen die Elemente aus, mit denen wir interagieren oder die wir prüfen möchten, simulieren Nutzereingaben und einen Button-Klick und überprüfen dann, ob die erwartete Nachricht im Paragraph erscheint. Der Test könnte so aussehen:
test('user interaction test', () => {
const { getByLabelText, getByText } = render(<MyComponent />);
const input = getByLabelText('message-input');
const button = getByText('Show Message');
const messageContainer = getByText('');
expect(messageContainer.textContent).toBe('');
fireEvent.change(input, { target: { value: 'Hello World' } });
fireEvent.click(button);
expect(messageContainer.textContent).toBe('Hello World');
});Gehen wir das Beispiel durch:
1. Wir importieren einige Helper von RTL sowie die zu testende Komponente.
2. Wir erstellen einen neuen Test und benennen ihn.
3. Wir verwenden die render-Methode von RTL, um die Komponente zu rendern. Diese liefert sogenannte Queries, mit denen wir die benötigten Elemente im Test auswählen können.
4. Mit den Queries wählen wir Input, Button und den Paragraph, in dem die Nachricht erscheint. Elemente lassen sich auf unterschiedliche Arten finden, auch wenn sie asynchron auftauchen, und wir können RegExp nutzen (wie hier, case-insensitive). Besonders interessant ist „getByLabelText“, weil wir damit den Input über das verknüpfte Label auswählen können. So prüfen wir auch die Accessibility unserer Inputs.
5. Anfangs sollte keine Nachricht angezeigt werden, daher testen wir darauf.
6. Wir simulieren eine Nutzereingabe.
7. Wir simulieren einen Klick auf den Button.
8. Wir fügen eine weitere Erwartung hinzu, dass der Nachrichten-Container den eingegebenen Wert enthält.
Hoffentlich besteht unser Test!
Frontend-Testing: End-to-End-Tests
Der letzte Teil der Testing Trophy sind End-to-End-Tests. E2E-Tests unterscheiden sich von anderen Testarten, weil sie in einem echten Browser laufen. Testfälle werden als Schritt-für-Schritt-Anweisungen formuliert, denen der automatisierte Browser durch die zu prüfenden Teile der App folgt.
Eines der beliebtesten Tools für End-to-End-Tests ist Cypress. Es ist leicht einzurichten, einfach zu bedienen und zudem schnell.
Ein Beispiel für einen End-to-End-Test eines Registrierungsformulars mit Cypress:
it('tests user registration', () => {
cy.visit('https://mywebsite.com/register');
cy.get('input[name="username"]').type('testUser');
cy.get('input[name="password"]').type('password123');
cy.get('button').contains('Register').click();
cy.url().should('include', '/login');
});In diesem Test navigieren wir zur Registrierungsseite, füllen Benutzername und Passwort aus, klicken auf den Register-Button und prüfen anschließend, ob wir zur Login-Seite weitergeleitet werden.
1. Wir erstellen unseren Test.
2. Wir sagen Cypress, es soll die URL mit dem Registrierungsformular aufrufen.
3. Wir greifen die entsprechenden Inputs und tippen Werte ein.
4. Wir suchen einen Button mit dem Text „Register“ und klicken ihn.
5. Nach erfolgreicher Registrierung sollten wir auf „/login“ umgeleitet werden – darauf testen wir.
Beim Ausführen des Tests öffnet sich ein Browserfenster, sodass wir jeden Schritt des Test-Runners sehen. Falls etwas schiefgeht, informiert uns Cypress.
In der Regel dauern End-to-End-Tests länger in der Erstellung als Unit- oder Integrationstests. Auch die Ausführung braucht mehr Zeit, da sie mit einer echten API kommunizieren. Deshalb sollten sie auf die kritischsten Flows der Anwendung fokussiert werden.
Zum Schluss: Frontend-Testing
Die Testing Trophy ist eine hervorragende Leitlinie. Wir starten mit statischen Tests, ergänzen Unit-Tests und schließen mit Integrationstests ab. Mit End-to-End-Tests automatisieren wir die wichtigsten Pfade der App. Schreib uns, um mehr über Frontend-Testing zu erfahren, oder an hello@start-up.house
Digital Transformation Strategy for Siemens Finance
Cloud-based platform for Siemens Financial Services in Poland


Das könnte Ihnen auch gefallen...

Speicherlecks in C++: Ursachen, Tools & wie Sie sie vermeiden?
Der Umgang mit Speicherlecks in C++ ist jetzt einfacher. Unser umfassender Leitfaden liefert Einblicke in Erkennungstools und Präventionsmethoden, mit denen Sie die Systemleistung verbessern und potenziellen Problemen vorbeugen. In unserem FAQ-Bereich finden Sie eine vertiefte Auseinandersetzung mit den häufigsten Fragen rund um Speicherlecks in C++.
Marek Majdak
19. Sept. 2023・5 Min. Lesezeit

5 einfache Schritte zu einem effektiven Bug Bash
Bug Bashes haben sich in Entwicklungsteams als beliebte Praxis etabliert, um die Fehlersuche zu beschleunigen und die Produktqualität zu steigern. Dieser Artikel erklärt, was Bug Bashes sind, welche Vorteile sie bieten und wann sie zum Einsatz kommen. Sie erhalten eine Schritt-für-Schritt-Anleitung, wie Sie einen erfolgreichen Bug Bash vorbereiten und durchführen – vom Definieren der Rollen und dem Abstecken des Testumfangs über die Erstellung von Bug-Report-Vorlagen bis hin zur Durchführung des eigentlichen Events. Außerdem zeigen wir, welche zusätzlichen Vorteile Bug Bashes über die reine Fehlersuche hinaus bieten, etwa die Förderung der Teamarbeit und ein tieferes Verständnis des Produktentwicklungszyklus.
Valeriia Oliinyk
02. Juni 2020・6 Min. Lesezeit

Was sind Randfälle in der Softwareentwicklung und im Softwaretest?
Edge Cases (Randfälle) spielen in der Softwareentwicklung eine zentrale Rolle; sie bestimmen oft die Zuverlässigkeit der Software und die User Experience. Wer diese besonderen Szenarien versteht, richtig priorisiert und gezielt testet, stellt die Robustheit des Produkts sicher. Dieser umfassende Leitfaden beleuchtet die Bedeutung von Edge Cases und zeigt, wie man sie souverän handhabt.
Marek Majdak
13. Juni 2022・5 Min. Lesezeit
Bereit, Ihr Know-how mit KI zu zentralisieren?
Beginnen Sie ein neues Kapitel im Wissensmanagement – wo der KI-Assistent zum zentralen Pfeiler Ihrer digitalen Support-Erfahrung wird.
Kostenlose Beratung buchenArbeiten Sie mit einem Team, dem erstklassige Unternehmen vertrauen.




