Golden Test (teste snapshot, teste de referência) — um método de teste visual de UI onde a renderização atual do componente é comparada com uma imagem de referência previamente salva (arquivo golden). Se as alterações de pixel excederem um limite definido, o teste falha e gera uma imagem diff. O desenvolvedor revisa o diff e aceita as alterações (atualiza o golden) ou corrige o bug. Leia mais em o artigo do Meta Engineering sobre Paparazzi.
Principais pontos
Golden Test é uma verificação automatizada da aparência visual de um componente por comparação pixel a pixel com uma referência. O processo: (1) o desenvolvedor ou testador cria o primeiro snapshot do componente — este é o “golden” (referência). (2) O arquivo golden é salvo no repositório junto ao teste. (3) Em execuções subsequentes, o teste renderiza o componente novamente e o compara com o golden salvo. (4) Se as imagens coincidirem — o teste passa. Se diferirem — o teste falha com um diff. Decisão: ou as alterações são esperadas (atualizar golden) ou é um bug.
Como o golden é gerado — a biblioteca renderiza o componente em um buffer fora da tela (Android: Canvas, iOS: UIGraphicsImageRenderer) sem uma tela real. Isso significa que golden tests funcionam no CI sem emulador de tela (virtual display), acelerando a execução. Paparazzi no Android usa Layoutlib do Android Studio — o mesmo motor do Layout Editor. iOSSnapshotTestCase usa renderização UIKit em CGImage. O resultado é um arquivo PNG de tamanho fixo.
Arquivos golden — um snapshot PNG de uma tela (1080x1920) ocupa 200–800 KB dependendo da complexidade. Para um projeto com 500 golden tests, são ~100–400 MB no repositório. Soluções: (1) armazenar golden no Git LFS. (2) Usar compressão PNG (pngcrush, oxipng). (3) Armazenar golden em armazenamento separado (S3) e baixar durante a compilação. Na IT Sectr armazenamos golden no Git LFS com limite de 1 MB por arquivo — suficiente para 90% dos testes.
Golden tests instáveis — o principal problema dos golden tests. GPUs diferentes, versões de fontes e anti-aliasing produzem microdiferenças nos pixels. Soluções: limite (percentual admissível de pixels diferentes), comparação difusa e execução em agentes CI idênticos (mesma GPU, SO, versão de emulador). Paparazzi usa comparação pixel-perfect, portanto os agentes CI devem ser idênticos.
Golden Test é um tipo de teste screenshot com uma referência fixa. O termo “golden” significa que a referência foi aprovada pela equipe e armazenada no repositório. Qualquer alteração de imagem requer uma decisão consciente do desenvolvedor: atualizar o golden ou corrigir o código. Golden Test funciona no nível de componentes individuais (Composable, UIView) e não requer um dispositivo real.
Screenshot Test é um conceito mais amplo. Um screenshot test pode capturar uma tela inteira com dados reais, navegação, barra de status do sistema e animações. Screenshot tests são frequentemente executados em dispositivos reais ou emuladores via UI Automator (Android) ou XCUITest (iOS). Golden tests são executados em ambiente de teste unitário (JVM, XCTest) sem emulador e capturam apenas um único componente.
| Característica | Golden Test | Screenshot Test |
|---|---|---|
| Nível | Componente/Composable/View | Tela inteira |
| Ambiente | Teste unitário (buffer fora da tela) | Dispositivo/Emulador |
| Velocidade | 50–200 ms por teste | 2–30 segundos por teste |
| Animações | Não suportadas | Suportadas (com pausas) |
| CI sem GPU | Funciona (Layoutlib) | Requer emulador |
| Complexidade de configuração | Baixa | Alta (Emulador/Device Farm) |
| Instabilidade | Média (GPUs diferentes) | Alta (emulador, tempo) |
Golden vs Screenshot — golden tests para verificar componentes UI individuais (botão, cartão, diálogo) em cada commit. Screenshot tests para verificação E2E de telas inteiras antes do lançamento. Golden tests fornecem feedback rápido ao desenvolvedor, screenshot tests dão confiança na integridade de toda a aplicação. Na IT Sectr usamos golden tests para Pull Requests (3–5 minutos) e screenshot tests noturnos (30–60 minutos).
Paparazzi — uma biblioteca da Cash App (Square) que renderiza componentes Android View e Jetpack Compose em PNG sem emulador. Usa Layoutlib (o mesmo motor do Android Studio Preview). Configuração: adicionar o plugin Gradle, escrever um teste com @Test e @RunWith(PaparazziRule::class), chamar paparazzi.snapshot(view). Paparazzi não suporta animações, vídeo nem Real Device — apenas renderização estática 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 — uma alternativa ao Paparazzi com suporte para Compose, View e comparação de imagens. Diferença: Roborazzi funciona via Robolectric e suporta um limite (percentual de diferença de pixel admissível). Isso reduz a instabilidade com GPUs diferentes no CI. Roborazzi também pode criar animações GIF das alterações (antes/depois/diff), o que é conveniente para revisão de código. Formato do arquivo golden: PNG + metadados JSON.
Atualização do golden — após uma alteração intencional de UI, o desenvolvedor exclui os arquivos golden antigos e executa os testes com o flag record. Paparazzi recria todos os arquivos golden. Então o desenvolvedor comita os novos arquivos golden junto com a alteração de código. Na revisão de código, o revisor vê o diff dos arquivos golden antigos e novos. Se as alterações forem aprovadas — o PR é mesclado. Se não — o desenvolvedor corrige o código e reinicia os testes. Nunca atualize arquivos golden automaticamente no CI — apenas localmente.
SwiftSnapshotTesting — uma biblioteca da pointfree.co, criadores do Composable Architecture. Suporta UIView, UIViewController, CALayer e SwiftUI View. Princípio: assertSnapshot(matching: view, as: .image). Na primeira execução, o golden é criado automaticamente. Nas execuções subsequentes, é comparado. Se a diferença exceder o limite admissível, o teste falha. SwiftSnapshotTesting funciona via UIGraphicsImageRenderer, que é compatível com 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) — uma biblioteca da Uber para UIKit. Ao contrário do SwiftSnapshotTesting, o iOSSnapshotTestCase requer especificar o tamanho da tela e a orientação. Os arquivos golden são PNG na pasta ReferenceImages. Vantagem: funciona com UIKit sem SwiftUI e suporta iOS 12+. Desvantagem: não atualiza golden automaticamente — deve ser executado com o flag record. SwiftSnapshotTesting é mais moderno e recomendado para novos projetos.
Golden específicos por dispositivo — arquivos golden diferem para diferentes tamanhos de tela e orientações. A abordagem padrão: nomear arquivos golden como TestName@3x~iPhone14.png. SwiftSnapshotTesting adiciona automaticamente um sufixo de dispositivo se o parâmetro .image(on: .iPhoneSe) for especificado. No Android, Paparazzi usa DeviceConfig para definir o tamanho. Armazene golden para cada fator de forma de dispositivo suportado separadamente. Não use um golden para tamanhos diferentes — isso levará a testes instáveis.
Pipeline CI — golden tests devem ser executados em cada Pull Request. Se um teste falhar, o CI mostra a imagem diff como um artefato de compilação. O desenvolvedor revisa o diff e toma uma decisão. Importante: arquivos golden gerados no CI nunca são commitados automaticamente. Apenas geração local pelo desenvolvedor após uma alteração intencional. GitHub Actions e GitLab CI suportam upload de artefatos (png, html) para visualizar diffs no navegador.
Tamanho do repositório — arquivos golden crescem rapidamente. 500 testes = 100–400 MB de PNG. Soluções: (1) Git LFS — cada golden é armazenado em LFS, clonado apenas no checkout. (2) Armazenar golden em um repositório separado e incluí-los como submódulo. (3) S3 + caching — golden no S3, CI baixa apenas arquivos alterados por checksum. Na IT Sectr usamos Git LFS com track *.png filter=lfs diff=lfs merge=lfs text=false. Localmente, golden estão em src/test/goldens/.
Revisão de código de golden — o git diff normal não mostra alterações PNG. Soluções: (1) GitHub abre imagens PNG ao clicar. (2) Usar Review Apps onde os diffs golden são visíveis no navegador. (3) Gerar um relatório HTML com colunas antes/depois/diff. Paparazzi cria um relatório HTML com três colunas: atual, esperado, diff. O relatório é anexado aos artefatos CI. Os revisores veem o relatório sem baixar arquivos localmente.
Quando atualizar o golden — apenas após uma alteração consciente de UI. Alteração de fonte, cor, espaçamento, ícone — o golden deve ser atualizado. Adicionar um novo botão, reorganizar elementos — o golden deve ser atualizado. Uma correção de bug que altera a aparência visual — o golden deve ser atualizado. Refatoração sem alterações de UI — o golden não deve mudar. Se um golden mudar sem alterações no código de UI — é um teste instável causado pelo ambiente, procure a causa nos agentes CI ou versões de dependências.
Perguntas frequentes
Golden Test — um teste snapshot no nível de componente em ambiente de teste unitário (rápido, sem emulador). Screenshot Test — captura a tela inteira em um dispositivo ou emulador (mais lento, mas realista). Golden funciona com buffer fora da tela, screenshot com uma tela real. Golden é adequado para CI em cada commit, screenshot para execuções noturnas antes do lançamento.
Principais causas: (1) GPUs diferentes no CI — use agentes CI idênticos. (2) Versões de fontes diferentes — fixe a versão do SO. (3) Anti-aliasing diferente — configure um limite (Roborazzi, iOSSnapshotTestCase). (4) Animações — desative animações nos testes. (5) Elementos do sistema (barra de status) — use uma configuração de dispositivo sem bordas. Paparazzi não é propenso a instabilidade graças ao Layoutlib.
Sim. Paparazzi tem suporte integrado para Compose via paparazzi.snapshot { }. Roborazzi também suporta Compose. No iOS, SwiftSnapshotTesting funciona com SwiftUI através de UIHostingController. Componentes Compose são renderizados via Layoutlib, SwiftUI via renderização UIKit. Limitação: animações Compose e SwiftUI não são suportadas — o golden test captura apenas o estado inicial.
Nunca automatize a aceitação de golden no CI. Apenas localmente: o desenvolvedor exclui arquivos golden antigos do diretório e executa testes com o flag record (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Os arquivos golden são recriados. O desenvolvedor revisa cada golden para verificar sua correção, comita as alterações junto com o código. A aceitação automática no CI levará a bugs de UI não detectados.
Golden tests são mais rápidos que testes instrumentados (UI Automator, XCUITest). Um golden test executa em 50–200 ms (Paparazzi: 100–150 ms em um MacBook Pro médio). 500 golden tests = 25–100 segundos. Compare com screenshot tests via emulador: 5–30 segundos por teste. Golden tests não desaceleram a compilação: 100 testes = ~15 segundos, o que é aceitável para verificação pré-mesclagem.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também