Was CI-Checks zuverlässig finden, und wo manuelles Testen unverzichtbar bleibt
Automatisierte Accessibility-Checks finden fehlende Labels, zu kleine Touch-Ziele und Kontrastfehler zuverlässig und lassen sich direkt in die CI-Pipeline einbauen, sodass ein Regressionsproblem auffällt, bevor es den Nutzer erreicht. Was sie nicht finden, ist, ob eine Screenreader-Ansage tatsächlich Sinn ergibt oder ob eine Navigationsreihenfolge für einen blinden Nutzer logisch ist. Dieser Artikel zeigt, welche Probleme sich in React Native automatisiert erkennen lassen, wie sich Accessibility-Checks in die CI-Pipeline integrieren lassen, und wo die Grenze zu manuellem Screenreader-Testing bewusst gezogen werden muss.
Inhaltsverzeichnis
- 1. Was automatisierte Accessibility-Tests leisten können und was nicht
- 2. Welche Probleme sich automatisiert zuverlässig erkennen lassen
- 3. Statische Analyse mit eslint-plugin-react-native-a11y
- 4. Laufzeit-Checks mit Detox und Accessibility-Snapshots
- 5. Farbkontrast automatisiert prüfen
- 6. Accessibility-Checks in die CI-Pipeline integrieren
- 7. Wo automatisierte Tests an ihre Grenzen stoßen
- 8. Manuelles Screenreader-Testing als notwendige Ergänzung
- 9. Accessibility-Kultur im Team etablieren
- 10. Zusammenfassung
- 11. FAQ
1. Was automatisierte Accessibility-Tests leisten können und was nicht
Barrierefreiheit wird in vielen Teams erst spät im Entwicklungsprozess geprüft, meist manuell und punktuell kurz vor einem Release, wodurch Probleme oft erst sehr spät auffallen und teuer zu beheben sind. Automatisierte Accessibility-Tests verschieben diese Prüfung strukturell nach vorn: Sie laufen bei jedem Pull Request, finden strukturelle Probleme, die sich formal aus dem Komponentenbaum ableiten lassen, und verhindern, dass bereits behobene Fehler unbemerkt wieder eingeführt werden.
Wichtig ist dabei ein realistisches Erwartungsmanagement: Automatisierte Werkzeuge erkennen zuverlässig, ob ein interaktives Element ein accessibilityLabel besitzt, ob ein Touch-Ziel die Mindestgröße unterschreitet oder ob ein Farbkontrast unter dem WCAG-Schwellenwert liegt. Ob die Reihenfolge, in der ein Screenreader durch einen Screen navigiert, für einen tatsächlichen Nutzer sinnvoll ist, oder ob eine Ansage inhaltlich verständlich formuliert ist, bleibt eine Frage, die kein automatisiertes Werkzeug beantworten kann, weil dafür echtes Nutzerverständnis nötig ist.
2. Welche Probleme sich automatisiert zuverlässig erkennen lassen
Fehlende accessibilityLabel-Angaben auf interaktiven Elementen wie TouchableOpacity oder Pressable sind der häufigste und am einfachsten automatisiert erkennbare Fehler, weil sich formal prüfen lässt, ob ein Element eine onPress-Prop besitzt, aber weder ein Label noch einen aus Textkindern ableitbaren zugänglichen Namen hat. Ebenso zuverlässig lässt sich die Touch-Ziel-Größe prüfen: Ein interaktives Element mit einer gerenderten Fläche unter den von Apple und Google empfohlenen vierundvierzig mal vierundvierzig beziehungsweise achtundvierzig mal achtundvierzig density-independent Pixeln lässt sich rein geometrisch aus dem Layout-Baum ermitteln.
Farbkontrast zwischen Text und Hintergrund lässt sich ebenfalls vollständig automatisiert berechnen, sofern beide Farbwerte zur Testzeit statisch bekannt sind, etwa über eine Kontrastformel nach WCAG, die einen numerischen Kontrastwert liefert und gegen den Schwellenwert von 4.5 zu 1 für normalen Text beziehungsweise 3 zu 1 für großen Text prüft. Zusätzlich lässt sich automatisiert prüfen, ob Bilder mit semantischer Bedeutung ein accessibilityLabel besitzen und ob rein dekorative Bilder korrekt mit accessibilityElementsHidden beziehungsweise importantForAccessibility="no" von der Screenreader-Navigation ausgeschlossen sind.
3. Statische Analyse mit eslint-plugin-react-native-a11y
Die einfachste Einstiegsstufe für automatisierte Accessibility-Prüfung ist ein ESLint-Plugin, das den Komponentenbaum bereits zur Entwicklungszeit statisch analysiert, ohne dass die App überhaupt gerendert werden muss. eslint-plugin-react-native-a11y prüft unter anderem, ob TouchableOpacity- und Pressable-Elemente ein accessibilityLabel besitzen, ob Bilder mit onPress-Handler zusätzlich als accessible markiert sind, und ob accessibilityRole korrekt gesetzt ist, wenn ein Element eine bestimmte Interaktionssemantik trägt.
Der große Vorteil dieser Ebene ist die Geschwindigkeit: ESLint-Regeln laufen in Millisekunden und lassen sich als Pre-Commit-Hook oder direkt im Editor als Live-Feedback einbinden, wodurch ein Entwickler Accessibility-Probleme oft schon beim Schreiben des Codes sieht, nicht erst in einem separaten CI-Schritt. Der Nachteil ist, dass rein statische Analyse keine tatsächlich gerenderten Layout-Maße kennt und deshalb Touch-Ziel-Größen oder tatsächliche Kontrastwerte, die von dynamischen Styles abhängen, nicht zuverlässig prüfen kann.
npm install --save-dev eslint-plugin-react-native-a11y
# .eslintrc.js
module.exports = {
plugins: ["react-native-a11y"],
extends: ["plugin:react-native-a11y/all"],
rules: {
"react-native-a11y/has-accessibility-hint": "warn",
"react-native-a11y/has-valid-accessibility-role": "error",
},
};
4. Laufzeit-Checks mit Detox und Accessibility-Snapshots
Statische Analyse allein deckt keine Probleme ab, die erst zur Laufzeit entstehen, etwa ein dynamisch berechnetes Label, das bei bestimmten Datenkombinationen leer bleibt, oder ein Touch-Ziel, dessen tatsächliche gerenderte Größe erst nach dem Layout-Pass feststeht. Detox erlaubt über getAttributes() den Zugriff auf tatsächlich gerenderte Accessibility-Eigenschaften eines Elements zur Testlaufzeit, wodurch sich gezielte Assertions schreiben lassen, die prüfen, ob ein Element im echten App-Zustand tatsächlich ein nicht-leeres Label und eine ausreichende Fläche besitzt.
Für die Touch-Ziel-Größe lässt sich die tatsächliche gerenderte Breite und Höhe eines Elements über getAttributes() auslesen und gegen die Mindestgröße von 44 mal 44 Punkten auf iOS beziehungsweise 48 mal 48 density-independent Pixeln auf Android prüfen. Diese Art von Test lässt sich systematisch für jeden interaktiven Screen der App als eigener Testfall in die bestehende E2E-Suite integrieren, ohne eine separate Accessibility-Test-Infrastruktur aufzubauen.
// e2e/accessibility/checkoutButton.a11y.test.ts
import { device, element, by } from "detox";
describe("Checkout Button - Accessibility", () => {
beforeEach(async () => {
await device.launchApp({ newInstance: true });
});
it("has a non-empty accessibility label and a valid touch target", async () => {
const button = element(by.id("checkout-submit-button"));
const attributes = await button.getAttributes();
expect(attributes.label).toBeTruthy();
expect(attributes.label.length).toBeGreaterThan(0);
// iOS: Mindestgröße 44x44pt, Android: 48x48dp
const minSize = device.getPlatform() === "ios" ? 44 : 48;
expect(attributes.frame.width).toBeGreaterThanOrEqual(minSize);
expect(attributes.frame.height).toBeGreaterThanOrEqual(minSize);
});
});
5. Farbkontrast automatisiert prüfen
Farbkontrast lässt sich am zuverlässigsten direkt im Design-System prüfen, bevor er überhaupt in Komponenten verwendet wird: Ein einfaches Skript, das jede definierte Text-Hintergrund-Kombination aus dem Farb-Token-System gegen die WCAG-Kontrastformel prüft, findet Verstöße bereits auf der Design-Token-Ebene, lange bevor eine einzelne Komponente gerendert wird. Das ist deutlich effizienter als Kontrastprüfung pro gerendertem Screen, weil sich ein Fehler auf Token-Ebene sonst potenziell in Dutzenden Screens gleichzeitig wiederholt.
Für Fälle, in denen Farben zur Laufzeit dynamisch berechnet werden, etwa bei nutzerspezifischen Theme-Farben oder Statusindikatoren, reicht eine reine Token-Prüfung nicht aus. Hier empfiehlt sich eine ergänzende Laufzeitprüfung, die tatsächlich gerenderte Farbwerte über einen Snapshot-Test extrahiert und gegen die Kontrastformel prüft, allerdings mit deutlich höherem Implementierungsaufwand als die Token-Ebene, weshalb sich dieser Aufwand meist nur für Bereiche mit tatsächlich dynamischen Farben lohnt.
6. Accessibility-Checks in die CI-Pipeline integrieren
Ein sinnvoller CI-Aufbau staffelt Accessibility-Checks nach Geschwindigkeit und Zuverlässigkeit: ESLint-Regeln laufen als schnellster Schritt bei jedem Push und blockieren einen Merge bereits bei offensichtlichen Fehlern wie fehlenden Labels. Detox-basierte Laufzeit-Checks laufen als Teil der bestehenden E2E-Suite, typischerweise etwas seltener, etwa nur bei Pull Requests statt bei jedem einzelnen Commit, weil sie einen echten Simulator- oder Emulator-Start benötigen und entsprechend mehr Zeit kosten.
Fehlgeschlagene Accessibility-Checks sollten, wie andere Testfehler auch, den Merge blockieren, nicht nur eine Warnung erzeugen, da Warnungen in der Praxis erfahrungsgemäß häufig ignoriert werden. Für bestehende Projekte mit vielen historisch gewachsenen Verstößen empfiehlt sich ein schrittweiser Rollout: neue und geänderte Screens werden sofort streng geprüft, während für unveränderten Altbestand zunächst nur eine Warnung ausgegeben wird, bis er im Rahmen regulärer Wartungsarbeiten nachgezogen wird.
7. Wo automatisierte Tests an ihre Grenzen stoßen
Ein Element kann ein technisch korrektes, nicht-leeres accessibilityLabel besitzen und trotzdem für einen Screenreader-Nutzer unbrauchbar sein, wenn das Label etwa nur "Button" statt einer konkreten Handlungsbeschreibung wie "Zur Kasse gehen" enthält. Kein automatisiertes Werkzeug kann beurteilen, ob ein Label inhaltlich verständlich und im Kontext sinnvoll ist, weil das echtes Sprachverständnis und Kenntnis der Nutzererwartung voraussetzt, nicht nur eine formale Prüfung auf Vorhandensein einer Zeichenkette.
Ebenso wenig lässt sich die logische Lese- und Navigationsreihenfolge eines Screens für einen Screenreader automatisiert bewerten, insbesondere bei komplexen Layouts mit mehreren nebeneinander positionierten Bereichen, bei denen die visuelle Anordnung nicht zwangsläufig der sinnvollen Ansage-Reihenfolge entspricht. Auch dynamisches Verhalten wie Live-Regionen, die Nutzer über asynchrone Zustandsänderungen informieren sollen, etwa eine Erfolgsmeldung nach dem Absenden eines Formulars, lässt sich nur bedingt automatisiert prüfen, weil das Timing und die tatsächliche Screenreader-Ansage stark plattform- und versionsabhängig sind.
8. Manuelles Screenreader-Testing als notwendige Ergänzung
Manuelles Testen mit VoiceOver auf iOS und TalkBack auf Android bleibt deshalb ein unverzichtbarer Bestandteil jedes ernsthaften Accessibility-Prozesses, insbesondere für neue, komplexe Screens und für kritische Flows wie Checkout oder Registrierung. Ein sinnvoller Testablauf navigiert den gesamten Screen ausschließlich über Screenreader-Gesten, ohne visuell auf den Bildschirm zu schauen, um zu erleben, ob die Reihenfolge und die Ansagen tatsächlich einen kohärenten Ablauf ergeben.
In der Praxis bewährt sich eine feste Kombination: automatisierte Checks als Sicherheitsnetz gegen Regressionen bei jedem Commit, ergänzt um eine manuelle Screenreader-Prüfung als fester Bestandteil des Review-Prozesses für jeden neuen oder wesentlich veränderten Screen, idealerweise durch jemanden, der regelmäßig mit assistiven Technologien arbeitet oder zumindest eine strukturierte Checkliste befolgt. Wo möglich, liefert Feedback von tatsächlichen Screenreader-Nutzern die verlässlichsten Erkenntnisse, die weder Automatisierung noch interne manuelle Tests vollständig ersetzen können.
9. Accessibility-Kultur im Team etablieren
Automatisierte Checks entfalten ihren vollen Nutzen erst, wenn sie in eine breitere Team-Praxis eingebettet sind: eine kurze Accessibility-Checkliste im Pull-Request-Template, ein regelmäßiger Termin, an dem neue Screens gemeinsam per Screenreader durchgegangen werden, und Design-Reviews, die Kontrastwerte und Touch-Ziel-Größen bereits vor der Implementierung prüfen, statt sie erst im Code zu korrigieren. Diese organisatorische Einbettung entscheidet oft stärker über den langfristigen Erfolg als die Wahl des konkreten Test-Werkzeugs.
Ein Team, das Accessibility ausschließlich als automatisierten CI-Schritt behandelt, wird zwar offensichtliche Regressionen verhindern, aber selten ein grundsätzlich gut zugängliches Produkt entwickeln, weil die wirklich schwierigen Entscheidungen, etwa wie ein komplexer Datenfilter für Screenreader-Nutzer sinnvoll strukturiert wird, menschliches Urteilsvermögen erfordern. Automatisierung und manuelles Testen sind deshalb keine Alternativen zueinander, sondern zwei notwendige Ebenen desselben Prozesses.
| Problem | Automatisiert erkennbar? | Werkzeug | Manuelle Prüfung nötig? |
|---|---|---|---|
| Fehlendes accessibilityLabel | Ja, zuverlässig | ESLint-Plugin, Detox getAttributes() | Nein, außer inhaltliche Qualität |
| Zu kleines Touch-Ziel | Ja, geometrisch messbar | Detox getAttributes() zur Laufzeit | Nein |
| Farbkontrast unter WCAG-Schwelle | Ja, bei statischen Farben | Token-Prüfskript, Kontrastformel | Nur bei dynamischen Farben ergänzend |
| Unverständlicher Label-Text | Nein | Kein automatisiertes Werkzeug geeignet | Ja, zwingend |
| Sinnvolle Navigationsreihenfolge | Nein | Kein automatisiertes Werkzeug geeignet | Ja, zwingend |
| Live-Region-Ansagen bei Zustandsänderung | Teilweise | Detox mit Einschränkungen | Ja, empfohlen |
Mironsoft
React-Native-App-Entwicklung und Magento-Anbindung
Eine mobile App zum Magento-Shop, die wirklich rund läuft?
Wir entwickeln React-Native-Apps, die sauber an die Magento REST- oder GraphQL-API angebunden sind, von der ersten Codezeile bis zur Veröffentlichung im App Store und bei Google Play.
App-Konzeption
Architektur und Feature-Umfang einer Magento-angebundenen App gemeinsam planen.
Magento-API-Integration
Produktkatalog, Warenkorb und Checkout sauber an die Shop-API anbinden.
Store-Veröffentlichung
App Store- und Google-Play-Freigabeprozess ohne Stolperfallen begleiten.
10. Zusammenfassung
Automatisierte Accessibility-Tests: Das Wichtigste auf einen Blick
Zuverlässig automatisierbar
Fehlende Labels, zu kleine Touch-Ziele und Farbkontrast lassen sich formal und geometrisch prüfen.
Zweistufige Toolchain
ESLint-Plugin für schnelle statische Checks, Detox getAttributes() für tatsächlich gerenderte Werte zur Laufzeit.
Klare Grenze
Inhaltliche Verständlichkeit von Labels und logische Navigationsreihenfolge bleiben menschliches Urteil.
Team-Praxis
Automatisierte CI-Checks und regelmäßiges manuelles Screenreader-Testing ergänzen sich, ersetzen sich nicht.