Golden Test (test snapshot, test de référence) — une méthode de test visuel de l’UI où le rendu actuel d’un composant est comparé à une image de référence préenregistrée (fichier golden). Si les changements de pixels dépassent un seuil défini, le test échoue et génère une image diff. Le développeur examine le diff et soit accepte les modifications (met à jour le golden), soit corrige le bug. En savoir plus dans l’article de Meta Engineering sur Paparazzi.
Points clés
Golden Test est une vérification automatisée de l’apparence visuelle d’un composant par comparaison pixel par pixel avec une référence. Le processus : (1) le développeur ou le testeur crée le premier snapshot du composant — c’est le « golden » (référence). (2) Le fichier golden est sauvegardé dans le dépôt à côté du test. (3) Lors des exécutions suivantes, le test rend le composant à nouveau et le compare au golden sauvegardé. (4) Si les images correspondent — le test est vert. Si elles diffèrent — le test est rouge avec un diff. Décision : soit les modifications sont attendues (mettre à jour le golden), soit c’est un bug.
Comment le golden est généré — la bibliothèque rend le composant dans un tampon hors écran (Android : Canvas, iOS : UIGraphicsImageRenderer) sans écran réel. Cela signifie que les golden tests fonctionnent sur le CI sans émulateur d’écran (affichage virtuel), ce qui accélère l’exécution. Paparazzi sur Android utilise Layoutlib d’Android Studio — le même moteur que l’éditeur de layout. iOSSnapshotTestCase utilise le rendu UIKit dans CGImage. Le résultat est un fichier PNG de taille fixe.
Fichiers golden — un snapshot PNG d’un écran (1080x1920) prend 200 à 800 Ko selon la complexité. Pour un projet avec 500 golden tests, cela représente ~100 à 400 Mo dans le dépôt. Solutions : (1) stocker les golden dans Git LFS. (2) Utiliser la compression PNG (pngcrush, oxipng). (3) Stocker les golden sur un stockage séparé (S3) et les télécharger lors de la compilation. Chez IT Sectr, nous stockons les golden dans Git LFS avec un seuil de 1 Mo par fichier — cela suffit pour 90 % des tests.
Tests golden instables — le principal problème des golden tests. Des GPU, versions de polices et anti-aliasing différents produisent des micro-différences dans les pixels. Solutions : seuil (pourcentage admissible de pixels différents), comparaison floue et exécution sur des agents CI identiques (même GPU, OS, version d’émulateur). Paparazzi utilise une comparaison pixel-perfect, donc les agents CI doivent être identiques.
Golden Test est un type de test screenshot avec une référence fixe. Le terme « golden » signifie que la référence a été approuvée par l’équipe et stockée dans le dépôt. Tout changement d’image nécessite une décision consciente du développeur : mettre à jour le golden ou corriger le code. Le Golden Test fonctionne au niveau des composants individuels (Composable, UIView) et ne nécessite pas de périphérique réel.
Screenshot Test est un concept plus large. Un test screenshot peut capturer un écran entier avec des données réelles, la navigation, la barre d’état système et des animations. Les tests screenshot sont souvent exécutés sur des appareils réels ou des émulateurs via UI Automator (Android) ou XCUITest (iOS). Les golden tests s’exécutent dans un environnement de test unitaire (JVM, XCTest) sans émulateur et ne capturent qu’un seul composant.
| Caractéristique | Golden Test | Screenshot Test |
|---|---|---|
| Niveau | Composant/Composable/View | Écran entier |
| Environnement | Test unitaire (tampon hors écran) | Appareil/Émulateur |
| Vitesse | 50 à 200 ms par test | 2 à 30 secondes par test |
| Animations | Non prises en charge | Prises en charge (avec pauses) |
| CI sans GPU | Fonctionne (Layoutlib) | Nécessite un émulateur |
| Complexité de configuration | Faible | Élevée (Émulateur/Device Farm) |
| Instabilité (Flakiness) | Moyenne (GPU différents) | Élevée (émulateur, temps) |
Golden vs Screenshot — les golden tests pour vérifier les composants UI individuels (bouton, carte, dialogue) à chaque commit. Les tests screenshot pour la vérification E2E des écrans entiers avant la publication. Les golden tests fournissent un retour rapide au développeur, les tests screenshot donnent confiance dans l’intégrité de l’application entière. Chez IT Sectr, nous utilisons les golden tests pour les Pull Requests (3 à 5 minutes) et les tests screenshot de nuit (30 à 60 minutes).
Paparazzi — une bibliothèque de Cash App (Square) qui rend les composants Android View et Jetpack Compose en PNG sans émulateur. Elle utilise Layoutlib (le même moteur que l’aperçu d’Android Studio). Configuration : ajouter le plugin Gradle, écrire un test avec @Test et @RunWith(PaparazziRule::class), appeler paparazzi.snapshot(view). Paparazzi ne prend pas en charge les animations, les vidéos ni les appareils réels — uniquement le rendu statique des composants.
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Golden test pour un composant Compose
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 — une alternative à Paparazzi avec prise en charge de Compose, View et de la comparaison d’images. Différence : Roborazzi fonctionne via Robolectric et prend en charge un seuil (pourcentage admissible de différence de pixels). Cela réduit l’instabilité avec différents GPU sur le CI. Roborazzi peut également créer des animations GIF des modifications (avant/après/diff), ce qui est pratique pour la révision de code. Format de fichier : PNG + métadonnées JSON.
Mise à jour du golden — après une modification intentionnelle de l’UI, le développeur supprime les anciens fichiers golden et exécute les tests avec le flag record. Paparazzi recrée tous les fichiers golden. Ensuite, le développeur commit les nouveaux fichiers golden avec la modification de code. Lors de la révision de code, le relecteur voit le diff des anciens et nouveaux fichiers golden. Si les modifications sont approuvées — la PR est fusionnée. Sinon — le développeur corrige le code et relance les tests. Ne mettez jamais à jour les fichiers golden automatiquement sur le CI — uniquement localement.
SwiftSnapshotTesting — une bibliothèque de pointfree.co, créateurs de Composable Architecture. Prend en charge UIView, UIViewController, CALayer et SwiftUI View. Principe : assertSnapshot(matching: view, as: .image). Lors de la première exécution, le golden est créé automatiquement. Lors des exécutions suivantes, il est comparé. Si la différence dépasse le seuil admissible, le test échoue. SwiftSnapshotTesting fonctionne via UIGraphicsImageRenderer, qui est compatible avec le 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 (anciennement FBSnapshotTestCase) — une bibliothèque d’Uber pour UIKit. Contrairement à SwiftSnapshotTesting, iOSSnapshotTestCase nécessite de spécifier la taille et l’orientation de l’écran. Les fichiers golden sont des PNG dans le dossier ReferenceImages. Avantage : fonctionne avec UIKit sans SwiftUI et prend en charge iOS 12+. Inconvénient : ne met pas à jour les golden automatiquement — doit être exécuté avec le flag record. SwiftSnapshotTesting est plus moderne et recommandé pour les nouveaux projets.
Golden spécifiques au périphérique — les fichiers golden diffèrent selon les tailles d’écran et les orientations. L’approche standard : nommer les fichiers golden comme TestName@3x~iPhone14.png. SwiftSnapshotTesting ajoute automatiquement un suffixe de périphérique si le paramètre .image(on: .iPhoneSe) est spécifié. Sur Android, Paparazzi utilise DeviceConfig pour définir la taille. Stockez les golden pour chaque facteur de forme de périphérique pris en charge séparément. N’utilisez pas un seul golden pour différentes tailles — cela entraînera des tests instables.
Pipeline CI — les golden tests doivent s’exécuter sur chaque Pull Request. Si un test échoue, le CI montre l’image diff comme artefact de construction. Le développeur examine le diff et prend une décision. Important : les fichiers golden générés sur le CI ne sont jamais commités automatiquement. Uniquement génération locale par le développeur après une modification intentionnelle. GitHub Actions et GitLab CI prennent en charge le téléchargement d’artefacts (png, html) pour visualiser les diffs dans le navigateur.
Taille du dépôt — les fichiers golden croissent rapidement. 500 tests = 100 à 400 Mo de PNG. Solutions : (1) Git LFS — chaque golden est stocké dans LFS, cloné uniquement lors du checkout. (2) Stocker les golden dans un dépôt séparé et les inclure comme sous-module. (3) S3 + mise en cache — golden sur S3, le CI télécharge uniquement les fichiers modifiés par somme de contrôle. Chez IT Sectr, nous utilisons Git LFS avec track *.png filter=lfs diff=lfs merge=lfs text=false. Localement, les golden se trouvent dans src/test/goldens/.
Révision de code des golden — le git diff normal n’affiche pas les modifications PNG. Solutions : (1) GitHub ouvre les images PNG au clic. (2) Utiliser Review Apps où les diffs golden sont visibles dans le navigateur. (3) Générer un rapport HTML avec les colonnes avant/après/diff. Paparazzi crée un rapport HTML avec trois colonnes : actuel, attendu, diff. Le rapport est joint aux artefacts CI. Les relecteurs consultent le rapport sans télécharger les fichiers localement.
Quand mettre à jour le golden — uniquement après une modification consciente de l’UI. Changement de police, couleur, marge, icône — le golden doit être mis à jour. Ajout d’un nouveau bouton, réorganisation des éléments — le golden doit être mis à jour. Correction de bug qui modifie l’apparence visuelle — le golden doit être mis à jour. Refactorisation sans changement d’UI — le golden ne doit pas changer. Si un golden change sans modification du code UI — c’est un test instable causé par l’environnement, cherchez la cause dans les agents CI ou les versions de dépendances.
Foire aux questions
Golden Test — un test snapshot au niveau composant dans un environnement de test unitaire (rapide, sans émulateur). Screenshot Test — capture l’écran entier sur un appareil ou émulateur (plus lent mais réaliste). Golden fonctionne avec un tampon hors écran, screenshot avec un écran réel. Golden convient au CI à chaque commit, screenshot pour les exécutions nocturnes avant la publication.
Causes principales : (1) GPU différents sur le CI — utilisez des agents CI identiques. (2) Versions de polices différentes — figez la version de l’OS. (3) Anti-aliasing différent — configurez un seuil (Roborazzi, iOSSnapshotTestCase). (4) Animations — désactivez les animations dans les tests. (5) Éléments système (barre d’état) — utilisez une configuration d’appareil sans bordure. Paparazzi n’est pas sujet à l’instabilité grâce à Layoutlib.
Oui. Paparazzi prend en charge nativement Compose via paparazzi.snapshot { }. Roborazzi prend également en charge Compose. Sur iOS, SwiftSnapshotTesting fonctionne avec SwiftUI via UIHostingController. Les composants Compose sont rendus via Layoutlib, SwiftUI via le rendu UIKit. Limitation : les animations Compose et SwiftUI ne sont pas prises en charge — le golden test ne capture que l’état initial.
N’automatisez jamais l’acceptation des golden sur le CI. Uniquement localement : le développeur supprime les anciens fichiers golden du répertoire et exécute les tests avec le flag record (Paparazzi : record=true, SwiftSnapshotTesting : record=true). Les fichiers golden sont recréés. Le développeur vérifie chaque golden pour s’assurer de sa correction, commit les modifications avec le code. L’acceptation automatique sur le CI entraînera des bugs UI non détectés.
Les golden tests sont plus rapides que les tests instrumentés (UI Automator, XCUITest). Un golden test s’exécute en 50 à 200 ms (Paparazzi : 100 à 150 ms sur un MacBook Pro moyen). 500 golden tests = 25 à 100 secondes. Comparez avec les tests screenshot via émulateur : 5 à 30 secondes par test. Les golden tests ne ralentissent pas la compilation : 100 tests = ~15 secondes, ce qui est acceptable pour une vérification pré-fusion.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi