Golden Test (snapshot-test, referentietesten) — methode voor visueel testen van UI waarbij de huidige render van een component wordt vergeleken met een vooraf opgeslagen referentieafbeelding (golden-bestand). Als pixelwijzigingen een ingestelde drempel overschrijden, faalt de test en genereert een diff-afbeelding. De ontwikkelaar bekijkt de diff en accepteert de wijzigingen (werkt golden bij) of herstelt de bug. Meer in het artikel van Meta Engineering over Paparazzi.
Belangrijkste punten
Golden Test — is een geautomatiseerde controle van het uiterlijk van een component door pixel-voor-pixel vergelijking met de referentie. Proces: (1) de ontwikkelaar of tester maakt de eerste opname van de component — dit is “golden” (de referentie). (2) Het golden-bestand wordt opgeslagen in de repository naast de test. (3) Bij volgende uitvoeringen rendert de test de component opnieuw en vergelijkt met de opgeslagen golden. (4) Als de afbeeldingen overeenkomen — is de test groen. Als ze verschillen — is de test rood met diff. Beslissing: of de wijzigingen zijn verwacht (we werken golden bij) of het is een bug.
Hoe wordt golden gegenereerd — de bibliotheek rendert de component in een off-screen buffer (Android: Canvas, iOS: UIGraphicsImageRenderer) zonder echt scherm. Dit betekent dat golden-testen op CI werken zonder schermemulator (virtual display), wat de uitvoering versnelt. Paparazzi op Android gebruikt Layoutlib uit Android Studio — dezelfde motor als Layout Editor. iOSSnapshotTestCase gebruikt UIKit-rendering naar CGImage. Resultaat — een PNG-bestand met vaste grootte.
Golden-bestanden — een PNG-opname van een scherm (1080x1920) neemt 200-800 KB in beslag, afhankelijk van de complexiteit. Voor een project met 500 golden-testen is dit ~100-400 MB in de repository. Oplossingen: (1) golden opslaan in Git LFS. (2) PNG-compressie gebruiken (pngcrush, oxipng). (3) Golden opslaan in aparte opslag (S3) en ophalen bij build. Bij IT Sectr bewaren we golden in Git LFS met een drempel van 1 MB per bestand — dit is voldoende voor 90% van de testen.
Flaky golden testen — het grootste probleem van golden-testen. Verschillende GPU's, lettertypeversies en anti-aliasing geven micro-verschillen in pixels. Oplossingen: threshold (toegestaan percentage verschillende pixels), fuzzy comparison (vervagende vergelijking) en uitvoeren op identieke CI-agenten (zelfde GPU, OS, emulatorversie). In Paparazzi wordt pixel-perfect vergelijking gebruikt, dus CI-agenten moeten identiek zijn.
Golden Test — is een vorm van screenshot-testen met een vaste referentie. De term “golden” betekent dat de referentie is goedgekeurd (geaccepteerd) door het team en wordt opgeslagen in de repository. Elke verandering van de afbeelding vereist een bewuste beslissing van de ontwikkelaar: golden bijwerken of code corrigeren. Golden Test werkt op het niveau van individuele componenten (Composable, UIView) en vereist geen echt apparaat.
Screenshot Test — een breder begrip. Screenshot-test kan het hele scherm vastleggen met echte gegevens, navigatie, systeemstatusbalk en animaties. Screenshot-testen worden vaak uitgevoerd op echte apparaten of emulators via UI Automator (Android) of XCUITest (iOS). Golden-testen werken in een unit-test omgeving (JVM, XCTest) zonder emulator en leggen slechts een enkele component vast.
| Kenmerk | Golden Test | Screenshot Test |
|---|---|---|
| Niveau | Component/Composable/View | Volledig scherm |
| Omgeving | Unit-test (off-screen buffer) | Apparaat/Emulator |
| Snelheid | 50-200 ms per test | 2-30 seconden per test |
| Animaties | Niet ondersteund | Ondersteund (met pauzes) |
| CI zonder GPU | Werkt (Layoutlib) | Vereist emulator |
| Configuratiecomplexiteit | Laag | Hoog (Emulator/Device Farm) |
| Flakiness | Gemiddeld (verschillende GPU) | Hoog (emulator, tijd) |
Golden vs Screenshot — golden-testen voor het controleren van individuele UI-componenten (knop, kaart, dialoog) bij elke commit. Screenshot-testen — voor E2E-controle van volledige schermen vóór release. Golden-testen geven snelle feedback aan de ontwikkelaar, screenshot-testen — vertrouwen in de integriteit van de hele applicatie. Bij IT Sectr gebruiken we golden-testen voor Pull Request (3-5 minuten) en screenshot-testen voor nightly (30-60 minuten).
Paparazzi — bibliotheek van Cash App (Square) die Android View- en Jetpack Compose-componenten naar PNG rendert zonder emulator. Gebruikt Layoutlib (dezelfde motor als Android Studio Preview). Configuratie: Gradle-plugin aansluiten, test schrijven met @Test en @RunWith(PaparazziRule::class), paparazzi.snapshot(view) aanroepen. Paparazzi ondersteunt geen animaties, video en Real Device — alleen statische render van componenten.
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Golden test voor een Compose-component
class ButtonGoldenTest {
@get:Rule
val paparazzi = Paparazzi(
Paparazzi.PaparazziSnapshotConfig(
deviceConfig = DeviceConfig.PIXEL_6,
theme = "android:Theme.Material.Light.NoActionBar"
)
)
@Test
fun primary_button() {
paparazzi.snapshot {
Button(
onClick = { },
modifier = Modifier.width(200.dp)
) {
Text("Submit")
}
}
}
}
Roborazzi — alternatief voor Paparazzi met ondersteuning voor Compose, View en afbeeldingsvergelijking. Verschil: Roborazzi werkt via Robolectric en ondersteunt threshold (percentage toegestane pixelverschil). Dit vermindert flakiness bij verschillende GPU's op CI. Roborazzi kan ook GIF-animaties van wijzigingen maken (voor/na/diff), wat handig is voor code review. Formaat van golden-bestanden: PNG + JSON-metadata.
Golden bijwerken — na een bewuste UI-wijziging verwijdert de ontwikkelaar oude golden-bestanden en voert de testen uit met de record-vlag. Paparazzi maakt alle golden-bestanden opnieuw aan. Vervolgens commit de ontwikkelaar de nieuwe golden samen met de codewijziging. In Code Review ziet de beoordelaar de diff van oude en nieuwe golden. Als wijzigingen zijn goedgekeurd — wordt de PR gemerged. Zo niet — de ontwikkelaar corrigeert de code en voert de testen opnieuw uit. Werk golden nooit automatisch bij op CI — alleen lokaal.
SwiftSnapshotTesting — bibliotheek van pointfree.co, makers van Composable Architecture. Ondersteunt UIView, UIViewController, CALayer en SwiftUI View. Principe: assertSnapshot(matching: view, as: .image). Bij de eerste uitvoering wordt golden automatisch aangemaakt. Bij volgende — vergeleken. Als het verschil de toegestane limiet overschrijdt — faalt de test. SwiftSnapshotTesting werkt via UIGraphicsImageRenderer, dat compatibel is met CI (Xcode Cloud, GitHub Actions).
import SnapshotTesting
import XCTest
final class ProfileCardSnapshotTests: XCTestCase {
func test_profile_card_default() {
let card = ProfileCard(
name: "Alice",
avatar: UIImage.testImage(),
badge: "Pro"
)
let controller = UIHostingController(rootView: card)
assertSnapshot(
matching: controller,
as: .image(on: .iPhoneSe),
record: ProcessInfo.processInfo
.environment["RECORD"] != nil
)
}
}
iOSSnapshotTestCase (voorheen FBSnapshotTestCase) — bibliotheek van Uber voor UIKit. In tegenstelling tot SwiftSnapshotTesting vereist iOSSnapshotTestCase het specificeren van schermgrootte en oriëntatie. Golden-bestanden — PNG in de map ReferenceImages. Voordeel: werkt met UIKit zonder SwiftUI en ondersteunt iOS 12+. Nadeel: werkt golden niet automatisch bij — moet worden uitgevoerd met record-vlag. SwiftSnapshotTesting is moderner en wordt aanbevolen voor nieuwe projecten.
Apparaatspecifieke golden — golden-bestanden verschillen voor verschillende schermformaten en oriëntaties. Standaard aanpak: golden benoemen als TestName@3x~iPhone14.png. SwiftSnapshotTesting voegt automatisch een apparaatsuffix toe als de parameter .image(on: .iPhoneSe) is gegeven. Op Android gebruikt Paparazzi DeviceConfig voor het instellen van de grootte. Bewaar golden voor elke ondersteunde device form factor apart. Gebruik geen enkele golden voor verschillende formaten — dit leidt tot flaky testen.
CI pipeline — golden-testen moeten bij elke Pull Request worden uitgevoerd. Als de test faalt, toont CI de diff-afbeelding als build-artefact. De ontwikkelaar bekijkt de diff en neemt een beslissing. Belangrijk: golden-bestanden gegenereerd op CI worden nooit automatisch gecommit. Alleen lokale generatie door de ontwikkelaar na een bewuste wijziging. GitHub Actions en GitLab CI ondersteunen het uploaden van artefacten (png, html) voor het bekijken van diff in de browser.
Repositorygrootte — golden-bestanden groeien snel. 500 testen = 100-400 MB PNG. Oplossingen: (1) Git LFS — elke golden wordt opgeslagen in LFS, alleen gekloond bij checkout. (2) Golden opslaan in een aparte repository en koppelen als submodule. (3) S3 + caching — golden op S3, CI downloadt alleen gewijzigde bestanden op basis van checksum. Bij IT Sectr gebruiken we Git LFS met track *.png filter=lfs diff=lfs merge=lfs text=false. Lokaal liggen golden in src/test/goldens/.
Code Review golden — gewone git diff toont geen PNG-wijzigingen. Oplossingen: (1) GitHub opent PNG-afbeeldingen bij klik. (2) Review Apps gebruiken, waar golden-diff zichtbaar is in de browser. (3) HTML-rapport genereren met kolommen voor/na/diff. Paparazzi maakt een HTML-rapport met drie kolommen: actual, expected, diff. Het rapport wordt bijgevoegd bij CI-artefacten. Beoordelaars bekijken het rapport zonder bestanden lokaal te downloaden.
Wanneer golden bijwerken — alleen na een bewuste UI-wijziging. Wijziging van lettertype, kleur, afstand, pictogram — golden moet worden bijgewerkt. Toevoegen van een nieuwe knop, herschikken van elementen — golden moet worden bijgewerkt. Bugfix die het uiterlijk verandert — golden moet worden bijgewerkt. Refactoring zonder UI-wijziging — golden moet niet worden bijgewerkt. Als golden verandert zonder UI-code wijziging — is dit een flaky test veroorzaakt door de omgeving, zoek de oorzaak in CI-agenten of afhankelijkheidsversies.
Veelgestelde vragen
Golden Test — snapshot-test op componentniveau in unit-test omgeving (snel, zonder emulator). Screenshot Test — vastleggen van het volledige scherm op apparaat of emulator (traag, maar realistisch). Golden werkt met off-screen buffer, screenshot — met echt scherm. Golden is geschikt voor CI bij elke commit, screenshot — voor nightly vóór release.
Belangrijkste oorzaken: (1) Verschillende GPU's op CI — gebruik identieke CI-agenten. (2) Verschillende lettertypeversies — fixeer de OS-versie. (3) Verschillende anti-aliasing — configureer threshold (Roborazzi, iOSSnapshotTestCase). (4) Animaties — schakel animaties uit in testen. (5) Systeemelementen (statusbalk) — gebruik randloze device config. Paparazzi is niet vatbaar voor flakiness vanwege Layoutlib.
Ja. Paparazzi heeft ingebouwde ondersteuning voor Compose via paparazzi.snapshot { }. Roborazzi ondersteunt ook Compose. Op iOS werkt SwiftSnapshotTesting met SwiftUI via UIHostingController. Compose-componenten worden gerenderd via Layoutlib, SwiftUI — via UIKit-rendering. Beperking: Compose- en SwiftUI-animaties worden niet ondersteund — golden-test legt alleen de beginstatus vast.
Automatiseer nooit het accepteren van golden op CI. Alleen lokaal: de ontwikkelaar verwijdert oude golden-bestanden uit de directory en voert testen uit met de record-vlag (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Golden-bestanden worden opnieuw aangemaakt. De ontwikkelaar controleert elke golden op correctheid, commit de wijzigingen samen met de code. Automatisch accepteren op CI leidt tot het missen van UI-fouten.
Golden-testen zijn sneller dan instrumentele testen (UI Automator, XCUITest). Eén golden-test wordt uitgevoerd in 50-200 ms (Paparazzi: 100-150 ms op een gemiddelde MacBook Pro). 500 golden-testen = 25-100 seconden. Vergelijk met screenshot-testen via emulator: 5-30 seconden per test. Golden-testen vertragen de build niet: 100 testen = ~15 seconden, wat acceptabel is voor pre-merge verificatie.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook