Tests mit React Native
Wir betrachten hier verschiedene Arten von Tests:
- Statische Analyse des Codes mit ESLint
- Unit-Test für einzelne JavaScript-/TypeScript-Funktionen
- Tests für React Native UI-Komponenten
- End-to-End-Tests für komplette App-Flows
Hinweis für Dozent: „Testpyramide“ in Excalidraw erstellen:
manuelle Tests
End-to-end tests
(Integrationstests)
UI-Komponenten-Tests
Unit-Tests für Funktionen
Linter: Tools zur Code-Analyse
Compiler für statische TypisierungStatische Code-Analyse mit ESLint
ESLint ist ein weit verbreitetes Tool zur statischen Code-Analyse in JavaScript- und TypeScript-Projekten. Es hilft, potenzielle Fehler, Stilprobleme und Best Practices im Code zu identifizieren.
Expo-Projekte enthalten bereits eine ESLint-Konfiguration, womit bereits viele Probleme im Code erkannt werden können:
- ungenutzte Variablen und Funktionen
- nicht erreichte Codeabschnitte
- potenzielle Fehlerquellen (z. B. falsche Vergleiche)
- Korrekte Nutzung von Hooks
- Allgemeine React/JSX-Regeln
- usw.
ESLint im Projekt ausführen:
npx expo lintUnit-Tests für Funktionen mit Jest
Zunächst betrachten wir Unit-Tests für einzelne Funktionen in JavaScript oder TypeScript.
Jest installieren
Anleitung für die Einrichtung Unit Tests mit Jest, siehe Abschnitt Installation and configuration mit den Schritten 1-3:
Test erstellen
Angenommen wir haben eine (viel zu einfache!) Funktion für das Validieren von Passwörtern (nur als Beispiel):
export function isValidPassword(input: string): boolean {
// Require at least 8 characters and one digit
return input.length >= 8 && /\d/.test(input);
}Wenn diese Funktion in einer Datei utils/password.ts liegt, dann
erstellen wir eine Test-Datei utils/password.test.ts mit folgendem Inhalt:
import { isValidPassword } from './password';
test('valid password', () => {
expect(isValidPassword('Password1')).toBe(true);
});
test('invalid password', () => {
expect(isValidPassword('Passwd1')).toBe(false);
});Die Test-Datei kann in einem beliebigen Unterordner liegen, wobei oft ein
Ordner names __tests__ verwendet wird. Solange die Dateien mit den Tests
auf .test.ts enden, werden sie von Jest durch das jest-expo-Preset gefunden
(siehe package.json nach der Installation). Die import-Pfade der zu testenden
Funktion müssen entsprechend angepasst werden.
Mit describe können auch mehrere Tests gruppiert werden:
import { isValidPassword } from './password';
test('valid password', () => {
expect(isValidPassword('Password1')).toBe(true);
});
describe('invalid password', () => {
test('invalid password - too short', () => {
expect(isValidPassword('Pass1')).toBe(false);
});
test('invalid password - no digit', () => {
expect(isValidPassword('Password')).toBe(false);
});
});Test ausführen
Wir haben bei der Installation von Jest (siehe oben) in der package.json
unter scripts einen Eintrag für den Test-Befehl hinzugefügt. Mit folgendem
Kommando können die Tests ausgeführt werden:
npm testJest startet damit im Watch-Modus und führt die Tests einmal direkt aus und jedes Mal, wenn eine Datei geändert wird.
Tipp: Mit KI-Tools lassen sich im Code zu testende Funktionen finden und passende Tests generieren. Hierbei ist natürlich kritisch zu prüfen, ob die generierten Tests auch wirklich sinnvoll sind.
Noch ein Tipp: KI-Agenten wollen die Test zur Überprüfung des generierten
Codes oft selbst ausführen. Dazu bietet es sich an, den Watch-Modus von
Jest im Test-Skript-Eintrag von package.json zu deaktivieren, denn
sonst blockiert der Watch-Modus den weiteren Ablauf:
"scripts": {
// ...
"test": "jest",
"test:watch": "jest --watchAll"
// ...
}Mit npm run test:watch kann der Watch-Modus weiterhin manuell gestartet werden.
Tests für UI-Komponenten mit React Native Testing Library
Mit Jest als Testrunner und der React Native Testing Library (RNTL) lassen sich React Native UI-Komponenten testen.
React Native Testing Library installieren
Siehe https://docs.expo.dev/develop/unit-testing/#install-react-native-testing-library
Im Dezember 2025 mussten wir für Expo 54 anders als im Link beschrieben RNTL so installieren:
npm install --save-dev react-test-renderer@19.1.0 @testing-library/react-nativeWebseite von RNTL: https://callstack.github.io/react-native-testing-library/
Beispiel für einen Komponententest
Wenn wir folgende Komponente in components/home.tsx haben:
import { StyleSheet, Text, View } from 'react-native';
export const CustomText = ({ children }) => <Text>{children}</Text>;
export default function Home() {
return (
<View style={styles.container}>
<CustomText>Welcome!</CustomText>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});Dann können wir einen UI-Komponententest z. B. in __tests__/components/home.test.tsx
erstellen:
import { render } from '@testing-library/react-native';
import Home, { CustomText } from '@/components/home';
describe('<Home />', () => {
test('Text renders correctly on HomeScreen', () => {
const { getByText } = render(<Home />);
getByText('Welcome!');
});
});Test ausführen
Da die UI-Komponententests mit Jest ausgeführt werden, können wir den gleichen Befehl wie bei den Unit-Tests verwenden:
npm testMit RNTL lassen sich auch Interaktionen wie Button-Klicks und Eingaben testen. Siehe die Dokumentation für weitere Beispiele: https://callstack.github.io/react-native-testing-library/
End-to-End-Tests mit Maestro
Maestro ist ein Open Source Testframework, mit dem komplette UI-Flows bzw. End-to-End-Tests via Skripts automatisiert werden können. Es ist plattformübergreifend und funktioniert mit nativen Android- und iOS-Apps, Flutter, React Native und Webanwendungen: https://maestro.dev
Maestro installieren
Siehe https://docs.maestro.dev/getting-started/installing-maestro/macos
Bei Bedarf Analytics deaktivieren:
export MAESTRO_CLI_NO_ANALYTICS=1Maestro nutzen
Die zu testende App sollte auf einem Android-Gerät, im Android Emulator oder iOS Simulator geöffnet sein.
Hinweis: App nur auf genau einem Gerät, Emulator oder Simulator starten, da Maestro scheinbar willkürlich das „erstbeste“ Gerät nimmt.
Für eine Todo-App, die in Expo Go läuft, könnte z. B. folgendes Skript
in einer Datei __tests__/maestro/first-flow.yaml erstellt werden:
appId: host.exp.Exponent # iOS Expo Go
---
- assertVisible: 'Todo hinzufügen'
- tapOn: 'Todo hinzufügen'
- inputText: 'Check out Maestro!'
- pressKey: Enter
- assertVisible: 'Check out Maestro!'Mit appId wird die App Expo Go angesteuert. Damit dieses Skript funktioniert,
sollte die zu testende App bereits in Expo Go gestartet sein.
Es ist auch möglich, mit folgendem Skript Expo Go zu starten und die passende App in Expo Go zu laden:
appId: host.exp.Exponent # iOS Expo Go
---
- openLink: 'exp://127.0.0.1:8081' # Replace with your Expo Go URL
- assertVisible: 'Todo hinzufügen'
- tapOn: 'Todo hinzufügen'
- inputText: 'Check out Maestro!'
- pressKey: Enter
- assertVisible: 'Check out Maestro!'Die passende URL für openLink ist in der Ausgabe von npx expo zu sehen.
Ausführung dieses Testskripts mit maestro test __tests__/maestro/first-flow.yaml.
Im Emulator/Simulator kann beobachtet werden, wie der UI-Test durchgeführt wird.
Sollten mehrere Skripte im Ordner __tests__/maestro liegen, dann können alle mit
diesem Befehl ausgeführt werden: maestro test __tests__/maestro
Maestro lässt sich in einem „continuous flow“ ausführen, sodass Änderungen an Test- oder Code-Dateien schneller und wiederholt überprüft werden können:
maestro test -c __tests__/maestro/first-flow.yamlMaestro hat umfangreiche Befehle und Selektoren:
- Befehle (commands): https://docs.maestro.dev/api-reference/commands
- Selektoren (selectors): https://docs.maestro.dev/api-reference/selectors
Alternativen zu Maestro
Appium (https://appium.io ) ist ebenfalls ein etabliertes und umfangreiches Open Source Testframework für End-to-End-Tests.
Für React Native gibt es mit Detox ein weiteres beliebtes Testframework: https://wix.github.io/Detox/
Weitere Testarten
- Integrationstests für mehrere Komponenten/Funktionen
- Tests für Expo Router (Navigation)
- API-/Service-Tests (Backend)
- Performance-Tests
- Accessibility-Tests
Nützliche Links zu Lernressourcen
- Allgemeine Infos zu Testing in React Native: https://reactnative.dev/docs/testing-overview
- Integrationstests mit Expo Router: https://docs.expo.dev/router/reference/testing/
- https://expo.dev/blog/how-to-build-a-solid-test-harness-for-expo-apps
- Maestro-Tests in der EAS-Cloud: https://docs.expo.dev/eas/workflows/examples/e2e-tests/
Im Quellcode der DHBW Lörrach Campus App finden sich Beispiele für verschiedene Testarten: https://github.com/DHBWLoerrach/campusapp