Golden Test (snapshot-test, pengujian referensi) — metode pengujian visual UI di mana render komponen saat ini dibandingkan dengan gambar referensi yang disimpan sebelumnya (file golden). Jika perubahan piksel melebihi ambang batas yang ditentukan, tes gagal dan menghasilkan gambar diff. Pengembang melihat diff dan baik menerima perubahan (memperbarui golden) atau memperbaiki bug. Selengkapnya di artikel Meta Engineering tentang Paparazzi.
Poin utama
Golden Test — adalah pemeriksaan otomatis tampilan komponen dengan membandingkan piksel per piksel dengan referensi. Proses: (1) pengembang atau tester mengambil tangkapan layar pertama komponen — ini adalah “golden” (referensi). (2) File golden disimpan di repositori di sebelah tes. (3) Pada proses selanjutnya, tes me-render komponen lagi dan membandingkannya dengan golden yang disimpan. (4) Jika gambar cocok — tes hijau. Jika berbeda — tes merah dengan diff. Keputusan: baik perubahan diharapkan (kami memperbarui golden) atau ini adalah bug.
Bagaimana golden dibuat — pustaka me-render komponen di buffer off-screen (Android: Canvas, iOS: UIGraphicsImageRenderer) tanpa layar nyata. Ini berarti golden-test bekerja di CI tanpa emulator layar (virtual display), yang mempercepat eksekusi. Paparazzi di Android menggunakan Layoutlib dari Android Studio — mesin yang sama dengan Layout Editor. iOSSnapshotTestCase menggunakan rendering UIKit ke CGImage. Hasilnya — file PNG dengan ukuran tetap.
File golden — tangkapan PNG satu layar (1080x1920) memakan 200-800 KB tergantung kompleksitasnya. Untuk proyek dengan 500 golden-test ini ~100-400 MB di repositori. Solusi: (1) menyimpan golden di Git LFS. (2) Menggunakan kompresi PNG (pngcrush, oxipng). (3) Menyimpan golden di penyimpanan terpisah (S3) dan mengambil saat build. Di IT Sectr kami menyimpan golden di Git LFS dengan ambang 1 MB per file — ini cukup untuk 90% tes.
Flaky golden test — masalah utama golden-test. GPU yang berbeda, versi font dan anti-aliasing memberikan perbedaan mikro pada piksel. Solusi: threshold (persentase piksel berbeda yang diizinkan), fuzzy comparison (perbandingan kabur), dan menjalankan pada agen CI yang identik (GPU, OS, versi emulator sama). Di Paparazzi digunakan perbandingan pixel-perfect, oleh karena itu agen CI harus identik.
Golden Test — adalah jenis screenshot-testing dengan referensi tetap. Istilah “golden” berarti referensi telah disetujui (diterima) oleh tim dan disimpan di repositori. Setiap perubahan gambar memerlukan keputusan sadar dari pengembang: memperbarui golden atau memperbaiki kode. Golden Test bekerja pada tingkat komponen individu (Composable, UIView) dan tidak memerlukan perangkat nyata.
Screenshot Test — konsep yang lebih luas. Screenshot-test dapat menangkap seluruh layar dengan data nyata, navigasi, bilah status sistem dan animasi. Screenshot-test sering dijalankan pada perangkat nyata atau emulator melalui UI Automator (Android) atau XCUITest (iOS). Golden-test bekerja di lingkungan unit-test (JVM, XCTest) tanpa emulator dan hanya menangkap satu komponen.
| Karakteristik | Golden Test | Screenshot Test |
|---|---|---|
| Tingkat | Komponen/Composable/View | Seluruh layar |
| Lingkungan | Unit-test (buffer off-screen) | Perangkat/Emulator |
| Kecepatan | 50-200 ms per tes | 2-30 detik per tes |
| Animasi | Tidak didukung | Didukung (dengan jeda) |
| CI tanpa GPU | Bekerja (Layoutlib) | Memerlukan emulator |
| Kompleksitas konfigurasi | Rendah | Tinggi (Emulator/Device Farm) |
| Flakiness | Sedang (GPU berbeda) | Tinggi (emulator, waktu) |
Golden vs Screenshot — golden-test untuk memeriksa komponen UI individu (tombol, kartu, dialog) di setiap commit. Screenshot-test — untuk pemeriksaan E2E seluruh layar sebelum rilis. Golden-test memberikan umpan balik cepat kepada pengembang, screenshot-test — keyakinan dalam integritas seluruh aplikasi. Di IT Sectr kami menggunakan golden-test untuk Pull Request (3-5 menit), dan screenshot-test untuk nightly (30-60 menit).
Paparazzi — pustaka dari Cash App (Square) yang me-render komponen Android View dan Jetpack Compose ke PNG tanpa emulator. Menggunakan Layoutlib (mesin yang sama dengan Android Studio Preview). Konfigurasi: menghubungkan plugin Gradle, menulis tes dengan @Test dan @RunWith(PaparazziRule::class), memanggil paparazzi.snapshot(view). Paparazzi tidak mendukung animasi, video dan Real Device — hanya render statis komponen.
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Golden test untuk komponen 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 — alternatif Paparazzi dengan dukungan Compose, View dan perbandingan gambar. Perbedaan: Roborazzi bekerja melalui Robolectric dan mendukung threshold (persentase perbedaan piksel yang diizinkan). Ini mengurangi flakiness dengan GPU berbeda di CI. Roborazzi juga dapat membuat animasi GIF perubahan (sebelum/sesudah/diff), yang nyaman untuk review kode. Format file golden: PNG + metadata JSON.
Memperbarui golden — setelah perubahan UI yang disengaja, pengembang menghapus file golden lama dan menjalankan tes dengan flag record. Paparazzi membuat ulang semua file golden. Kemudian pengembang melakukan commit golden baru bersama dengan perubahan kode. Dalam review kode, pengulas melihat diff golden lama dan baru. Jika perubahan disetujui — PR digabungkan. Jika tidak — pengembang memperbaiki kode dan menjalankan ulang tes. Jangan pernah memperbarui golden secara otomatis di CI — hanya secara lokal.
SwiftSnapshotTesting — pustaka dari pointfree.co, pencipta Composable Architecture. Mendukung UIView, UIViewController, CALayer dan SwiftUI View. Prinsip: assertSnapshot(matching: view, as: .image). Pada proses pertama, golden dibuat secara otomatis. Pada proses berikutnya — dibandingkan. Jika perbedaan melebihi batas yang diizinkan — tes gagal. SwiftSnapshotTesting bekerja melalui UIGraphicsImageRenderer, yang kompatibel dengan 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 (sebelumnya FBSnapshotTestCase) — pustaka dari Uber untuk UIKit. Tidak seperti SwiftSnapshotTesting, iOSSnapshotTestCase memerlukan penentuan ukuran layar dan orientasi. File golden — PNG di folder ReferenceImages. Kelebihan: bekerja dengan UIKit tanpa SwiftUI dan mendukung iOS 12+. Kekurangan: tidak memperbarui golden secara otomatis — harus dijalankan dengan flag record. SwiftSnapshotTesting lebih modern dan direkomendasikan untuk proyek baru.
Golden khusus perangkat — file golden berbeda untuk ukuran layar dan orientasi yang berbeda. Pendekatan standar: memberi nama golden sebagai TestName@3x~iPhone14.png. SwiftSnapshotTesting secara otomatis menambahkan sufiks perangkat jika parameter .image(on: .iPhoneSe) diberikan. Di Android, Paparazzi menggunakan DeviceConfig untuk mengatur ukuran. Simpan golden untuk setiap faktor bentuk perangkat yang didukung secara terpisah. Jangan gunakan satu golden untuk ukuran berbeda — ini akan menyebabkan tes flaky.
CI pipeline — golden-test harus dijalankan di setiap Pull Request. Jika tes gagal, CI menampilkan gambar diff sebagai artefak build. Pengembang melihat diff dan mengambil keputusan. Penting: file golden yang dihasilkan di CI tidak pernah di-commit secara otomatis. Hanya pembuatan lokal oleh pengembang setelah perubahan yang disengaja. GitHub Actions dan GitLab CI mendukung unggahan artefak (png, html) untuk melihat diff di browser.
Ukuran repositori — file golden tumbuh dengan cepat. 500 tes = 100-400 MB PNG. Solusi: (1) Git LFS — setiap golden disimpan di LFS, hanya dikloning saat checkout. (2) Menyimpan golden di repositori terpisah dan menghubungkannya sebagai submodul. (3) S3 + caching — golden di S3, CI hanya mengunduh file yang diubah berdasarkan checksum. Di IT Sectr kami menggunakan Git LFS dengan track *.png filter=lfs diff=lfs merge=lfs text=false. Secara lokal, golden berada di src/test/goldens/.
Review kode golden — git diff biasa tidak menunjukkan perubahan PNG. Solusi: (1) GitHub membuka gambar PNG saat diklik. (2) Menggunakan Review Apps, di mana golden-diff terlihat di browser. (3) Menghasilkan laporan HTML dengan kolom sebelum/sesudah/diff. Paparazzi membuat laporan HTML dengan tiga kolom: actual, expected, diff. Laporan dilampirkan ke artefak CI. Pengulas melihat laporan tanpa mengunduh file secara lokal.
Kapan memperbarui golden — hanya setelah perubahan UI yang disengaja. Perubahan font, warna, spasi, ikon — golden harus diperbarui. Penambahan tombol baru, penataan ulang elemen — golden harus diperbarui. Perbaikan bug yang mengubah tampilan — golden harus diperbarui. Refactoring tanpa perubahan UI — golden tidak boleh diperbarui. Jika golden berubah tanpa perubahan kode UI — ini adalah tes flaky yang disebabkan oleh lingkungan, cari penyebabnya di agen CI atau versi dependensi.
Pertanyaan yang sering diajukan
Golden Test — snapshot-test di tingkat komponen dalam lingkungan unit-test (cepat, tanpa emulator). Screenshot Test — menangkap seluruh layar pada perangkat atau emulator (lambat, tetapi realistis). Golden bekerja dengan buffer off-screen, screenshot — dengan layar nyata. Golden cocok untuk CI di setiap commit, screenshot — untuk nightly sebelum rilis.
Penyebab utama: (1) GPU berbeda di CI — gunakan agen CI yang identik. (2) Versi font berbeda — tetapkan versi OS. (3) Anti-aliasing berbeda — konfigurasikan threshold (Roborazzi, iOSSnapshotTestCase). (4) Animasi — matikan animasi dalam tes. (5) Elemen sistem (bilah status) — gunakan device config tanpa bingkai. Paparazzi tidak rentan terhadap flakiness karena Layoutlib.
Ya. Paparazzi memiliki dukungan bawaan untuk Compose melalui paparazzi.snapshot { }. Roborazzi juga mendukung Compose. Di iOS, SwiftSnapshotTesting bekerja dengan SwiftUI melalui UIHostingController. Komponen Compose di-render melalui Layoutlib, SwiftUI — melalui rendering UIKit. Keterbatasan: animasi Compose dan SwiftUI tidak didukung — golden-test hanya menangkap keadaan awal.
Jangan pernah mengotomatiskan penerimaan golden di CI. Hanya secara lokal: pengembang menghapus file golden lama dari direktori dan menjalankan tes dengan flag record (Paparazzi: record=true, SwiftSnapshotTesting: record=true). File golden dibuat ulang. Pengembang memeriksa setiap golden untuk kebenaran, melakukan commit perubahan bersama dengan kode. Penerimaan otomatis di CI akan menyebabkan bug UI terlewatkan.
Golden-test lebih cepat daripada tes instrumental (UI Automator, XCUITest). Satu golden-test dijalankan dalam 50-200 ms (Paparazzi: 100-150 ms pada MacBook Pro rata-rata). 500 golden-test = 25-100 detik. Bandingkan dengan screenshot-test melalui emulator: 5-30 detik per tes. Golden-test tidak memperlambat build: 100 tes = ~15 detik, yang dapat diterima untuk verifikasi pre-merge.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga