Snapshot-Testing für mobile Anwendungen: Funktionsweise, Tools und Beispiele

Autor: IT Sectr Veröffentlicht: 2026-04-07 Lesezeit: 9 Min.

Snapshot-Testing ist eine Methode zur automatisierten Überprüfung der Benutzeroberfläche, bei der der aktuelle Bildschirmzustand mit einem Referenzbild (Snapshot) verglichen wird, das beim vorherigen Testlauf gespeichert wurde. Jede visuelle Abweichung wird als Änderung erfasst, die eine Bestätigung durch den Entwickler erfordert. Im Gegensatz zu UI-Tests, die das Vorhandensein von Elementen prüfen, erkennen Snapshottests pixelgenaue Veränderungen — Verschiebungen, Farbabweichungen und Layoutprobleme. Laut Android Developers, 2024 erkennt Snapshot-Testing bis zu 30 % der visuellen Regressionen, die von herkömmlichen UI-Tests übersehen werden, was es zu einem unverzichtbaren Werkzeug für die Aufrechterhaltung einer konsistenten Oberfläche macht.

Wichtige Punkte

  • Snapshot-Testing — eine Methode zum Vergleich der aktuellen Bildschirmdarstellung mit einem Referenzbild zur Erkennung visueller Regressionen.
  • Paparazzi — eine Android-Bibliothek, die Compose- und View-Komponenten in einer Testumgebung ohne Emulator rendert.
  • Shot — ein Android-Framework, das Screenshots realer Bildschirme in Instrumentationstests mit Unterstützung verschiedener Auflösungen erstellt.
  • SnapshotTesting — eine Bibliothek von Point-Free für iOS, die nicht nur Bilder, sondern auch Text, JSON und Core Data vergleichen kann.
  • Aktualisierung von Referenzen — ein einmaliger Befehl nach einer bewussten Änderung der Oberfläche, der alte Snapshots durch neue ersetzt.

Was ist Snapshot-Testing?

Snapshot-Testing ist eine Technik, bei der ein Test eine UI-Komponente rendert, das resultierende Bild als Referenz speichert und bei späteren Ausführungen die aktuelle Darstellung mit dieser Referenz vergleicht. Stimmen die Bilder überein — besteht der Test. Werden Unterschiede festgestellt — schlägt der Test fehl, und der Entwickler erhält ein Diff-Bild mit hervorgehobenen geänderten Pixeln. Die Technik wurde aus der Webentwicklung (Jest Snapshots) übernommen und für mobile Plattformen adaptiert.

Der Hauptwert von Snapshottests liegt in der automatischen Erkennung unerwarteter visueller Änderungen. Ein Entwickler könnte das Farbschema in einem globalen Thema ändern und versehentlich ein Dutzend Bildschirme beeinflussen. UI-Tests, die das Vorhandensein von Schaltflächen und Texten prüfen, bemerken dies nicht. Ein Snapshottest erfasst jede Pixeländerung auf jedem betroffenen Bildschirm und liefert ein vollständiges Bild der Auswirkungen der Änderung.

Laut einer Umfrage des Mobile DevOps Summit 2023 reduzieren Teams, die Snapshottests zusätzlich zu klassischen UI-Tests einsetzen, die Anzahl visueller Fehler in Releases um 40 %. Dieser Ansatz ist besonders effektiv in Projekten mit Designsystemen und komponentenbasierten Architekturen, wo die Änderung einer Basiskomponente Dutzende von Anwendungsbildschirmen betreffen kann.

Wie unterscheiden sich Snapshottests von UI-Tests

Der grundlegende Unterschied liegt im Prüfobjekt. UI-Tests überprüfen das Vorhandensein, den Zustand und das Verhalten von Oberflächenelementen: „Die Schaltfläche ist sichtbar“, „Der Text enthält eine Fehlermeldung“, „Nach dem Drücken öffnet sich ein neuer Bildschirm“. Snapshottests prüfen das gesamte visuelle Erscheinungsbild: Elementpositionierung, Abstände, Farben, Schriftarten, Schatten und abgerundete Ecken. Ein Snapshottest beantwortet die Frage „Sieht der Bildschirm wie erwartet aus?“, während ein UI-Test die Frage beantwortet „Funktioniert der Bildschirm wie erwartet?“

Auch die Ausführungsgeschwindigkeit unterscheidet sich. UI-Tests laufen auf einem Emulator oder echten Gerät, erfordern ein vollständiges Laden der Anwendung und dauern 10 Sekunden bis eine Minute pro Szenario. Snapshottests mit Bibliotheken wie Paparazzi rendern Komponenten in einer virtuellen Umgebung ohne Emulatorstart, was die Testzeit auf 100–500 Millisekunden reduziert. Ein vollständiger Satz von Snapshottests (50–100 Bildschirme) wird in 2–5 Minuten ausgeführt, statt 30–60 Minuten für einen vergleichbaren Satz von UI-Tests.

Snapshottests ersetzen jedoch keine UI-Tests. Die optimale Strategie ist eine Kombination: Snapshottests decken visuelle Regressionen ab (Darstellung jedes Bildschirms in Grundzuständen), während UI-Tests die verhaltensbezogenen Aspekte abdecken (Klickszenarien, Eingabevalidierung, Navigation). Diese Kombination bietet 90 % Vertrauen in die Korrektheit der Oberfläche bei minimaler CI-Laufzeit.

Werkzeuge für Snapshot-Testing

Auf Android sind die wichtigsten Werkzeuge Paparazzi und Shot. Paparazzi von Cash App rendert Komponenten in einer JVM-Testumgebung ohne Emulator und verwendet das Gravity-Layout von Layoutlib. Shot von Karumi erstellt Instrumentation-Screenshots auf einem echten Gerät oder Emulator und vergleicht sie über die Bibliothek AShot mit Referenzen, wobei Unterschiede in Auflösung und Pixeldichte berücksichtigt werden.

Paparazzi für Android

Paparazzi benötigt keinen Emulatorstart — das Rendering erfolgt auf der JVM über Layoutlib, was eine mit Unit-Tests vergleichbare Geschwindigkeit bietet. Die Bibliothek unterstützt sowohl das View-System als auch Jetpack Compose. Für Compose wird der Modifikator paparazzi.snapshot { MyComposable() } verwendet. Referenzen werden in src/test/snapshots gespeichert und bei jedem Lauf automatisch verglichen. Der maximale Unterschiedsprozentsatz wird über maxPercentDifference konfiguriert.

SnapshotTesting für iOS

SnapshotTesting von Point-Free unterstützt den Vergleich nicht nur von UIImage, sondern auch von Strings, JSON, Data und ganzen Core Data Stores. Dies macht es zu einem vielseitigen Werkzeug nicht nur für UI-Snapshots, sondern auch für die Überprüfung der Serialisierung und Dekodierung von JSON-Antworten. Für SwiftUI wird die assertSnapshot-Erweiterung mit dem Modifikator .image(on: .iPhone13) verwendet. Die Strategie record: true erstellt Referenzen beim ersten Lauf.

Plattformübergreifende Ansätze

Für React Native ist die beliebte Lösung react-native-testing-library in Kombination mit jest-image-snapshot. Der Web-Ansatz für Snapshottests wird in die mobile Umgebung übertragen, indem Komponenten in einer Node.js-Umgebung gerendert und anschließend JSON-Snapshots des virtuellen DOM verglichen werden. Dieser Ansatz ist schneller als nativer Code, aber weniger genau — er berücksichtigt keine plattformspezifischen Schriftartendarstellungen und Systemkomponenteneigenschaften. Für Flutter wird Golden-Testing über das goldens-Toolkit verwendet.

Codebeispiele für Snapshottests

Betrachten wir Snapshottests für Android (Paparazzi) und iOS (SnapshotTesting). Beide Beispiele überprüfen das Erscheinungsbild einer Komponente — einer Benutzerkarte mit Avatar, Name und Status. Der Test rendert die Komponente mit Testdaten und vergleicht das Ergebnis mit einem im Repository gespeicherten Referenzbild.

Android: Snapshottest mit Paparazzi

Paparazzi verwendet die @Test-Annotation und die snapshot()-Methode, um das Rendering zu erfassen. Referenzen werden im Ordner src/test/snapshots gespeichert und beim nächsten Lauf automatisch zum Vergleich geladen.

kotlin
class UserCardSnapshotTest {

    @get:Rule
    val paparazzi = Paparazzi(
        theme = "Theme.MyApp",
        maxPercentDifference = 0.1
    )

    @Test
    fun userCard_defaultState() {
        val card = UserCard(
            name = "Alice Johnson",
            status = "Online",
            avatarUrl = "https://example.com/avatar.png"
        )
        paparazzi.snapshot(card)
    }

    @Test
    fun userCard_offlineState() {
        val card = UserCard(
            name = "Bob Smith",
            status = "Offline",
            avatarUrl = null
        )
        paparazzi.snapshot(card, name = "user_card_offline")
    }
}

iOS: Snapshottest mit SnapshotTesting

SnapshotTesting verwendet den .snapshot()-Modifikator innerhalb von assertSnapshot. Die Bibliothek bestimmt automatisch das Format — UIImage für UIView, String für Text, Data für Binärdaten.

swift
import SnapshotTesting
import XCTest

class UserCardSnapshotTests: XCTestCase {
    func testUserCardDefaultState() {
        let card = UserCardView(
            name: "Alice Johnson",
            status: "Online",
            avatarURL: URL(string: "https://example.com/avatar.png")
        )
        let controller = UIHostingController(rootView: card)
        assertSnapshot(matching: controller, as: .image(on: .iPhone13))
    }

    func testUserCardOfflineState() {
        let card = UserCardView(
            name: "Bob Smith",
            status: "Offline",
            avatarURL: nil
        )
        assertSnapshot(matching: card, as: .image(on: .iPhone13))
    }
}

Workflow des Snapshot-Testing

Ein typischer Workflow umfasst vier Phasen. Erster Lauf (Aufnahmemodus): Alle Snapshottests werden im Aufnahmemodus ausgeführt — Referenzbilder werden erstellt und im Repository gespeichert. Diese Phase wird bei der ersten Testeinrichtung oder nach einer bewussten Änderung der Oberfläche durchgeführt. Nach der Aufnahme werden die Referenzen zusammen mit dem Code committet — sie werden Teil des Projekts.

Bei späteren Läufen arbeiten die Tests im Vergleichsmodus: Jede neue Darstellung wird mit der Referenz verglichen. Werden Unterschiede festgestellt, wird ein Diff-Bild generiert: Pixel, die mit der Referenz übereinstimmen, werden grün hervorgehoben, abweichende Pixel rot. Der Entwickler untersucht das Diff und entscheidet: Ist die Änderung erwartet (bewusste Designänderung), wird die Referenz mit dem Aufnahmebefehl aktualisiert; ist sie unerwartet, wird der Fehler behoben. Die Aktualisierung von Referenzen erfolgt mit einem einzigen Befehl: Für Paparazzi ist es `./gradlew recordPaparazzi`, für SnapshotTesting — `assertSnapshot(record: true)`.

Laut dem Spotify Engineering Blog (2022) verbringen Teams, die den beschriebenen Workflow verwenden, durchschnittlich 2 Minuten pro Test mit der Analyse von Diff-Bildern. Bei einem Satz von 50 Snapshottests dauert ein vollständiger Referenzaktualisierungszyklus 15–20 Minuten, was deutlich schneller ist als die manuelle Überprüfung visueller Änderungen auf 50 Bildschirmen.

Einschränkungen und Antipattern von Snapshottests

Snapshottests haben grundlegende Einschränkungen. Umgebungsempfindlichkeit: Dieselbe Komponente kann auf verschiedenen OS-Versionen, Bildschirmdichten und Schriftkonfigurationen unterschiedlich dargestellt werden. Auf einem Rechner erstellte Referenzen können sich von der Darstellung auf einem CI-Server unterscheiden. Die Lösung besteht darin, feste Umgebungsparameter zu verwenden: eine bestimmte Layoutlib-Version für Paparazzi oder ein exaktes Gerätemodell für SnapshotTesting.

Antipattern Nr. 1: Riesige Snapshots — ein Snapshottest, der den gesamten Bildschirm erfasst, schlägt bei jeder kleinsten Änderung an einer beliebigen Komponente fehl. Der richtige Ansatz ist, einzelne Komponenten (Schaltfläche, Karte, Eingabefeld) isoliert zu testen. Jede Komponente wird unabhängig getestet, was eine genaue Identifizierung der Änderungsquelle ermöglicht. Antipattern Nr. 2: Diffs ignorieren — das automatische Aktualisieren von Referenzen ohne Analyse der Diff-Bilder reduziert den Wert von Snapshottests auf null. Jedes Diff erfordert eine bewusste Entscheidung des Entwicklers.

Laut dem Better Engineering Blog (2023) bieten Snapshottests den größten Nutzen, wenn sie Komponenten des Designsystems und wichtige Bildschirme in Grundzuständen abdecken — leer, gefüllt, Fehler und Grenzfall. Das Abdecken von Animationen und dynamischen Zuständen durch Snapshottests ist aufgrund der nicht deterministischen Natur von Zeitstempeln beim Rendering ineffizient — für solche Szenarien sind Videoaufzeichnungen oder manuelle QA-Prüfungen besser geeignet.

Häufig gestellte Fragen

Ersetzen Snapshottests UI-Tests?

Nein, Snapshottests prüfen das visuelle Erscheinungsbild, während UI-Tests das Verhalten der Oberfläche prüfen. Die optimale Strategie ist die Kombination beider Ansätze: Snapshots für visuelle Regression, UI-Tests für Szenarien und Navigation. Snapshots beantworten „Sieht es richtig aus?“, UI-Tests beantworten „Funktioniert es richtig?“.

Wie oft sollten Referenzbilder aktualisiert werden?

Referenzen werden bei jeder bewussten Designänderung aktualisiert: neue Themenfarbe, geänderte Abstände, Hinzufügen oder Entfernen von Elementen. Die Aktualisierung erfolgt über den Aufnahmemodus, wonach die Diff-Bilder im Code-Review überprüft werden, um sicherzustellen, dass die Änderungen den Erwartungen des Designers entsprechen.

Welche Komponenten sollten mit Snapshottests abgedeckt werden?

In erster Linie Komponenten des Designsystems — Schaltflächen, Karten, Eingabefelder, modale Fenster. Dann wichtige Bildschirme in Grundzuständen. Testen Sie nicht mit Snapshots Animationen, WebView, Karten und Bildschirme mit dynamischem Inhalt — Snapshots erzeugen hier aufgrund von Nichtdeterminismus falsche Fehlschläge.

Wie geht man mit falschen Fehlschlägen aufgrund unterschiedlicher OS-Versionen um?

Verwenden Sie dieselbe API-Stufe für Aufnahme- und Testmodus. Für Paparazzi geben Sie eine bestimmte Layoutlib-Version in der Konfiguration an. Für SnapshotTesting legen Sie das Gerätemodell fest. Auf Android 14 erstellte Referenzen können sich aufgrund von Änderungen in Systemschriftarten und dem Material-Design von der Darstellung auf Android 12 unterscheiden.

Snapshottests in CI — wie einrichten?

In CI laufen Snapshottests im Überprüfungsmodus (verify). Schlägt ein Test fehl, zeigt CI das Diff-Bild in den Build-Artefakten an. Der Aufnahmemodus (Referenzaktualisierung) wird lokal vom Entwickler oder in einer separaten CI-Aufgabe mit manuellem Trigger ausgeführt. Referenzbilder müssen in das Repository committet werden.

Zusammenfassung

  • Snapshot-Testing vergleicht die aktuelle Komponentendarstellung mit einem Referenzbild und erkennt Pixeländerungen und visuelle Regressionen.
  • Paparazzi — ein schnelles Android-Tool ohne Emulator; SnapshotTesting — eine vielseitige iOS-Bibliothek von Point-Free.
  • Snapshottests ersetzen keine UI-Tests — sie ergänzen sie: Snapshots für das Visuelle, UI-Tests für das Verhalten.
  • Aufnahmemodus erstellt Referenzbilder; der Überprüfungsmodus vergleicht aktuelle Darstellungen damit und generiert bei Abweichungen Diffs.
  • Designsystemkomponenten sind ein vorrangiges Ziel für Snapshottests, da ihre Änderungen mehrere Bildschirme betreffen.
  • Jedes Diff erfordert eine bewusste Entwicklerentscheidung — das automatische Ersetzen von Referenzen ohne Analyse macht den Wert der Tests zunichte.
  • Referenzbilder werden in das Repository committet und sind zusammen mit dem Testquellcode Teil der Codebasis.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch