Golden Test (prueba snapshot, prueba de referencia) es un método de prueba visual de UI donde el renderizado actual del componente se compara con una imagen de referencia previamente guardada (archivo golden). Si los cambios de píxeles superan un umbral establecido, la prueba falla y genera una imagen diff. El desarrollador revisa el diff y acepta los cambios (actualiza el golden) o corrige el error. Más información en el artículo de Meta Engineering sobre Paparazzi.
Puntos clave
Golden Test es una verificación automatizada de la apariencia visual de un componente mediante comparación píxel a píxel con un estándar. El proceso: (1) el desarrollador o testeador crea la primera captura del componente — este es el “golden” (estándar). (2) El archivo golden se guarda en el repositorio junto al test. (3) En ejecuciones posteriores, el test vuelve a renderizar el componente y lo compara con el golden guardado. (4) Si las imágenes coinciden — el test es verde. Si difieren — el test es rojo con un diff. Decisión: o los cambios son esperados (actualizar golden) o es un error.
Cómo se genera el golden — la biblioteca renderiza el componente en un buffer fuera de pantalla (Android: Canvas, iOS: UIGraphicsImageRenderer) sin pantalla real. Esto significa que los golden tests funcionan en CI sin emulador de pantalla (virtual display), acelerando la ejecución. Paparazzi en Android usa Layoutlib de Android Studio — el mismo motor que el Layout Editor. iOSSnapshotTestCase usa renderizado UIKit en CGImage. El resultado es un archivo PNG de tamaño fijo.
Archivos golden — una captura PNG de una pantalla (1080x1920) ocupa 200–800 KB según la complejidad. Para un proyecto con 500 golden tests, son ~100–400 MB en el repositorio. Soluciones: (1) guardar golden en Git LFS. (2) Usar compresión PNG (pngcrush, oxipng). (3) Guardar golden en un almacenamiento separado (S3) y descargarlos al compilar. En IT Sectr guardamos golden en Git LFS con un límite de 1 MB por archivo — suficiente para el 90% de los tests.
Golden tests inestables — el principal problema de los golden tests. Diferentes GPU, versiones de fuentes y antialiasing producen microdiferencias en los píxeles. Soluciones: umbral (porcentaje admisible de píxeles diferentes), comparación difusa y ejecución en agentes CI idénticos (misma GPU, SO, versión de emulador). Paparazzi usa comparación pixel-perfect, por lo que los agentes CI deben ser idénticos.
Golden Test es un tipo de prueba screenshot con un estándar fijo. El término “golden” significa que el estándar ha sido aprobado por el equipo y se almacena en el repositorio. Cualquier cambio de imagen requiere una decisión consciente del desarrollador: actualizar el golden o corregir el código. Golden Test funciona a nivel de componentes individuales (Composable, UIView) y no requiere un dispositivo real.
Screenshot Test es un concepto más amplio. Un screenshot test puede capturar una pantalla completa con datos reales, navegación, barra de estado del sistema y animaciones. Los screenshot tests a menudo se ejecutan en dispositivos reales o emuladores mediante UI Automator (Android) o XCUITest (iOS). Los golden tests se ejecutan en un entorno de pruebas unitarias (JVM, XCTest) sin emulador y capturan solo un componente individual.
| Característica | Golden Test | Screenshot Test |
|---|---|---|
| Nivel | Componente/Composable/View | Pantalla completa |
| Entorno | Prueba unitaria (buffer fuera de pantalla) | Dispositivo/Emulador |
| Velocidad | 50–200 ms por test | 2–30 segundos por test |
| Animaciones | No soportadas | Soportadas (con pausas) |
| CI sin GPU | Funciona (Layoutlib) | Requiere emulador |
| Complejidad de configuración | Baja | Alta (Emulador/Device Farm) |
| Inestabilidad (Flakiness) | Media (diferentes GPU) | Alta (emulador, tiempo) |
Golden vs Screenshot — golden tests para verificar componentes UI individuales (botón, tarjeta, diálogo) en cada commit. Screenshot tests para verificación E2E de pantallas completas antes del lanzamiento. Los golden tests proporcionan retroalimentación rápida al desarrollador, los screenshot tests brindan confianza en la integridad de toda la aplicación. En IT Sectr usamos golden tests para Pull Requests (3–5 minutos) y screenshot tests nocturnos (30–60 minutos).
Paparazzi — una biblioteca de Cash App (Square) que renderiza componentes Android View y Jetpack Compose en PNG sin emulador. Usa Layoutlib (el mismo motor que Android Studio Preview). Configuración: agregar el plugin de Gradle, escribir un test con @Test y @RunWith(PaparazziRule::class), llamar paparazzi.snapshot(view). Paparazzi no soporta animaciones, video ni Real Device — solo renderizado estático de componentes.
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Golden test para componente 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 — una alternativa a Paparazzi con soporte para Compose, View y comparación de imágenes. Diferencia: Roborazzi funciona mediante Robolectric y soporta un umbral (porcentaje de diferencia de píxeles admisible). Esto reduce la inestabilidad con diferentes GPU en CI. Roborazzi también puede crear animaciones GIF de los cambios (antes/después/diff), lo que es conveniente para la revisión de código. Formato de archivo golden: PNG + metadatos JSON.
Actualización del golden — después de un cambio intencional de UI, el desarrollador elimina los archivos golden antiguos y ejecuta los tests con el flag record. Paparazzi recrea todos los archivos golden. Luego el desarrollador confirma los nuevos archivos golden junto con el cambio de código. En la revisión de código, el revisor ve el diff de los archivos golden antiguos y nuevos. Si los cambios se aprueban — el PR se fusiona. Si no — el desarrollador corrige el código y reinicia los tests. Nunca actualice los archivos golden automáticamente en CI — solo localmente.
SwiftSnapshotTesting — una biblioteca de pointfree.co, creadores de Composable Architecture. Soporta UIView, UIViewController, CALayer y SwiftUI View. Principio: assertSnapshot(matching: view, as: .image). En la primera ejecución, el golden se crea automáticamente. En ejecuciones posteriores, se compara. Si la diferencia supera el umbral admisible, la prueba falla. SwiftSnapshotTesting funciona mediante UIGraphicsImageRenderer, que es compatible con 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 (anteriormente FBSnapshotTestCase) — una biblioteca de Uber para UIKit. A diferencia de SwiftSnapshotTesting, iOSSnapshotTestCase requiere especificar el tamaño de pantalla y la orientación. Los archivos golden son PNG en la carpeta ReferenceImages. Ventaja: funciona con UIKit sin SwiftUI y soporta iOS 12+. Desventaja: no actualiza los golden automáticamente — debe ejecutarse con el flag record. SwiftSnapshotTesting es más moderno y se recomienda para proyectos nuevos.
Golden específicos por dispositivo — los archivos golden difieren para diferentes tamaños de pantalla y orientaciones. El enfoque estándar: nombrar los golden como TestName@3x~iPhone14.png. SwiftSnapshotTesting agrega automáticamente un sufijo de dispositivo si se especifica el parámetro .image(on: .iPhoneSe). En Android, Paparazzi usa DeviceConfig para establecer el tamaño. Almacene golden para cada factor de forma de dispositivo compatible por separado. No use un mismo golden para diferentes tamaños — esto generará tests inestables.
Pipeline CI — los golden tests deben ejecutarse en cada Pull Request. Si un test falla, CI muestra la imagen diff como un artefacto de compilación. El desarrollador revisa el diff y toma una decisión. Importante: los archivos golden generados en CI nunca se confirman automáticamente. Solo generación local por parte del desarrollador después de un cambio intencional. GitHub Actions y GitLab CI admiten la carga de artefactos (png, html) para ver diffs en el navegador.
Tamaño del repositorio — los archivos golden crecen rápidamente. 500 tests = 100–400 MB de PNG. Soluciones: (1) Git LFS — cada golden se almacena en LFS, se clona solo al hacer checkout. (2) Almacenar golden en un repositorio separado e incluirlos como submódulo. (3) S3 + almacenamiento en caché — golden en S3, CI descarga solo los archivos modificados por checksum. En IT Sectr usamos Git LFS con track *.png filter=lfs diff=lfs merge=lfs text=false. Localmente, los golden se encuentran en src/test/goldens/.
Revisión de código de golden — el git diff normal no muestra cambios PNG. Soluciones: (1) GitHub abre imágenes PNG al hacer clic. (2) Usar Review Apps donde los diffs golden son visibles en el navegador. (3) Generar un informe HTML con columnas antes/después/diff. Paparazzi crea un informe HTML con tres columnas: actual, esperado, diff. El informe se adjunta a los artefactos de CI. Los revisores ven el informe sin descargar archivos localmente.
Cuándo actualizar el golden — solo después de un cambio consciente de UI. Cambio de fuente, color, relleno, icono — el golden debe actualizarse. Agregar un nuevo botón, reordenar elementos — el golden debe actualizarse. Una corrección de error que cambia la apariencia visual — el golden debe actualizarse. Refactorización sin cambios de UI — el golden no debe cambiar. Si un golden cambia sin cambios en el código de UI — es un test inestable causado por el entorno, busque la causa en los agentes CI o las versiones de dependencias.
Preguntas frecuentes
Golden Test — una prueba snapshot a nivel de componente en un entorno de prueba unitaria (rápida, sin emulador). Screenshot Test — captura la pantalla completa en un dispositivo o emulador (más lento, pero realista). Golden funciona con buffer fuera de pantalla, screenshot con una pantalla real. Golden es adecuado para CI en cada commit, screenshot para ejecuciones nocturnas antes del lanzamiento.
Principales causas: (1) Diferentes GPU en CI — use agentes CI idénticos. (2) Diferentes versiones de fuentes — fije la versión del SO. (3) Diferente antialiasing — configure un umbral (Roborazzi, iOSSnapshotTestCase). (4) Animaciones — desactive las animaciones en los tests. (5) Elementos del sistema (barra de estado) — use una configuración de dispositivo sin bordes. Paparazzi no es propenso a inestabilidad gracias a Layoutlib.
Sí. Paparazzi tiene soporte integrado para Compose mediante paparazzi.snapshot { }. Roborazzi también soporta Compose. En iOS, SwiftSnapshotTesting funciona con SwiftUI a través de UIHostingController. Los componentes Compose se renderizan mediante Layoutlib, SwiftUI mediante renderizado UIKit. Limitación: no se soportan animaciones de Compose y SwiftUI — el golden test captura solo el estado inicial.
Nunca automatice la aceptación de golden en CI. Solo localmente: el desarrollador elimina los archivos golden antiguos del directorio y ejecuta los tests con el flag record (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Los archivos golden se recrean. El desarrollador revisa cada golden para verificar su corrección, confirma los cambios junto con el código. La aceptación automática en CI dará lugar a errores de UI no detectados.
Los golden tests son más rápidos que los tests instrumentados (UI Automator, XCUITest). Un golden test se ejecuta en 50–200 ms (Paparazzi: 100–150 ms en un MacBook Pro promedio). 500 golden tests = 25–100 segundos. Compare con los screenshot tests mediante emulador: 5–30 segundos por test. Los golden tests no ralentizan la compilación: 100 tests = ~15 segundos, lo cual es aceptable para la verificación previa a la fusión.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también