Screenshot Test는 애플리케이션 화면의 스크린샷을 캡처하여 참조 이미지와 비교함으로써 사용자 인터페이스를 자동으로 확인하는 방법입니다. 골든 테스트와 달리 스크린샷 테스트는 실제 기기 또는 에뮬레이터에서 수행되며, 탐색, 시스템 요소 및 애니메이션을 포함한 전체 화면을 캡처하고, 애플리케이션과 상호 작용하기 위해 UI Automator(Android) 또는 XCUITest(iOS)를 사용합니다. 자세한 내용은 Android UI Automator 문서를 참조하세요.
주요 내용
Screenshot Test는 테스트가 애플리케이션 화면을 열고, 작업(탭, 텍스트 입력, 스크롤)을 수행한 후 결과 상태의 스크린샷을 찍는 종단 간 사용자 인터페이스 테스트입니다. 스크린샷은 저장소에 저장된 베이스라인과 비교됩니다. 스크린샷이 다르면 테스트가 실패합니다. 스크린샷 테스트는 단위 테스트로는 볼 수 없는 시각적 회귀(잘못된 여백, 요소 겹침, 잘못된 색상)를 감지합니다.
골든 테스트가 있는데 왜 스크린샷 테스트가 필요한가? — 골든 테스트는 개별적으로 구성 요소를 확인합니다: 하나의 버튼, 하나의 카드, 하나의 텍스트. 스크린샷 테스트는 프로덕션에 최대한 가까운 환경에서 전체 화면을 확인합니다: 실제 탐색, 실제 데이터(또는 최대한 현실적인 모의 데이터), 실제 시스템 글꼴, 실제 상태 표시줄. 오직 스크린샷 테스트만이 실제 기기에서 버튼이 다른 요소와 겹치는 것을 보여줍니다.
비즈니스 가치 — Google(2023)에 따르면, 시각적 버그는 모든 모바일 애플리케이션 버그의 15-25%를 차지합니다. 스크린샷 테스트는 이전에 QA 엔지니어가 수동으로 수행하던 시각적 품질 확인을 자동화합니다. 하나의 스크린샷 테스트는 한 화면의 5-10분 수동 테스트를 대체합니다. 50개 화면을 가진 애플리케이션의 경우, 회귀 테스트 실행당 4-8인시를 절약합니다. 스크린샷 테스트는 2-3 릴리스 주기 내에 투자 비용을 회수합니다.
골든 테스트는 더 빠르고 간단합니다: 오프스크린 버퍼에서 구성 요소를 렌더링하는 데 밀리초가 걸리며, 기기가 필요 없고 CI에서 안정적입니다. 스크린샷 테스트는 더 현실적입니다: 시스템 요소가 포함된 실제 화면을 캡처하고, 애니메이션과 탐색을 지원하며, 실제 기기에서 작동합니다. 선택은 목표에 따라 다릅니다: 개발자를 위한 빠른 피드백(골든) 또는 릴리스 전 최대 현실성(스크린샷).
| 특성 | Screenshot Test | Golden Test |
|---|---|---|
| 속도 | 2-30초 | 50-200ms |
| 현실성 | 최대(실제 기기) | 제한적(오프스크린) |
| 기기 필요 | 예(에뮬레이터/실물) | 아니요(JVM, XCTest) |
| 애니메이션 | 지원 | 미지원 |
| 탐색 | 다단계 시나리오 | 단일 구성 요소 |
| 불안정성 | 높음(네트워크, 타이밍) | 중간(GPU, 글꼴) |
| 병렬성 | Device Farm(Firebase, AWS) | 멀티스레드 JVM/XCTest |
Golden + Screenshot — 구성 요소 라이브러리(Design System)의 각 UI 구성 요소에 골든 테스트를 사용하세요. 시각적 회귀의 80%는 구성 요소 수준에서 발견됩니다. 스크린샷 테스트는 중요한 사용자 경로(온보딩, 로그인, 결제 흐름, 장바구니)에 사용합니다. 실제 화면에서 구성 요소 통합과 관련된 20%의 회귀는 스크린샷 테스트로만 발견됩니다. IT Sectr에서는 80/20 비율을 사용합니다: 골든 400개 + 스크린샷 100개.
스크린샷 테스트가 필요하지 않은 경우 — 화면이 상호 작용 없이 정적 콘텐츠로 구성된 경우, 골든 구성 요소 테스트가 더 낮은 비용으로 동일한 수준의 검증을 제공합니다. 화면이 동적으로 변경되는 경우(피드, 채팅), 스크린샷 테스트는 복잡한 데이터 설정과 대기 시간이 필요합니다. 이러한 경우 기본 상태(빈 목록, 로딩)에는 스크린샷을, 목록의 개별 카드에는 골든을 사용하세요.
UI Automator는 애플리케이션 간 UI 테스트를 위한 Android 프레임워크입니다. UiDevice.takeScreenshot()을 통해 스크린샷을 찍을 수 있습니다. Espresso(단일 애플리케이션 내에서 작동)와 달리, UI Automator는 시스템 대화상자(권한, 알림) 및 다른 애플리케이션과 상호 작용할 수 있습니다. UI Automator에서 스크린샷 테스트: 앱 열기, 로딩 대기, 스크린샷 찍기, 베이스라인과 비교.
class LoginScreenScreenshotTest {
@get:Rule
val rule = ComposeTestRule.createAndroidComposeRule<MainActivity>()
@Test
fun login_screen_default() {
val device = UiDevice.getInstance(
InstrumentationRegistry.getInstrumentation()
)
// 화면 로딩 대기
IdlingRegistry.getInstance().waitForIdle()
// 스크린샷 촬영
val screenshot = device.takeScreenshot()
val golden = loadGolden("login_default.png")
// 기준 이미지와 비교
val diff = ImageComparator.compare(screenshot, golden)
assertTrue(diff.similarity > 0.98)
}
}
Firebase Test Lab은 수백 대의 실제 기기에서 병렬로 계측 테스트를 실행하기 위한 Google Cloud 서비스입니다. Firebase Test Lab의 스크린샷 테스트는 다양한 기기(Pixel 7, Galaxy S24, Xiaomi 14)에서 스크린샷을 캡처하고 베이스라인과 비교합니다. 장점: 하나의 테스트가 20개 기기에서 10-15분 안에 UI를 확인합니다. 단점: 비용(20개 기기에서 테스트당 $1-5). Firebase Test Lab은 gcloud CLI 또는 Gradle 플러그인을 통해 CI와 통합됩니다.
Shot은 Android에서 스크린샷 테스트를 간소화하는 라이브러리입니다. Shot은 Espresso와 UI Automator 위에서 작동하며, 골든 관리(생성, 업데이트, 삭제), 임계값과의 비교(픽셀 또는 백분율) 및 HTML 보고서 생성을 추가합니다. Shot은 자체 이미지 비교 인프라를 작성하지 않고 신속하게 스크린샷 테스트를 구현하려는 프로젝트에 적합합니다.
XCUITest는 iOS, iPadOS 및 tvOS 애플리케이션의 UI 테스트를 위한 Apple의 프레임워크입니다. XCUITest의 스크린샷 테스트는 화면 캡처에 XCUIScreen.main.screenshot()을, 스크린샷 저장에 XCAttachment를 사용합니다. XCUITest는 사용자 작업(탭, 스와이프, typeText)을 시뮬레이션하고 각 단계 후에 스크린샷을 찍습니다. Xcode 16+에서는 XCTAttachment를 통한 베이스라인과의 스크린샷 비교 기본 지원이 추가되었습니다.
final class LoginScreenScreenshotTests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
super.setUp()
app = XCUIApplication()
app.launch()
}
func test_login_initial_state() {
let loginButton = app.buttons["login_button"]
XCTAssertTrue(loginButton.exists)
// 스크린샷 촬영
let screenshot = app.screenshot()
let attachment = XCTAttachment(screenshot: screenshot)
attachment.name = "Login-Screen-Initial"
attachment.lifetime = .keepAlways
add(attachment)
// 기준 이미지와 비교 (XCTAttachment + golden 필요)
assertScreenshot(
screenshot: screenshot,
goldenName: "login_initial_state"
)
}
}
Xcode Cloud는 iOS 애플리케이션을 빌드하고 테스트하기 위한 Apple의 클라우드 CI입니다. Xcode Cloud는 시뮬레이터에서 XCUITest 테스트 실행을 지원합니다. 스크린샷 테스트는 여러 시뮬레이터에서 병렬로 실행할 수 있습니다(iPhone 15, iPhone 15 Pro Max, iPad Pro). 결과: 첨부 파일이 포함된 XCResult Bundle. Xcode Cloud는 GitHub/GitLab에 내장되어 있지 않습니다 — 통합에는 Xcode Cloud Webhooks를 사용하세요. 대안: macos-14 및 xcodebuild를 사용한 GitHub Actions.
비교 프레임워크 — iOSSnapshotTestCase(Uber)는 시뮬레이터에서 실행하면 스크린샷 테스트에도 작동합니다. SwiftSnapshotTesting(pointfree)은 구성 요소 골든 테스트에 더 중점을 둡니다. iOS에서 스크린샷 테스트를 위해 기본 제공 XCUITest 도구 + XCTAttachment + 사용자 정의 ImageComparator(Pixelmator 또는 AImage)를 사용하세요. CI에서는 시뮬레이터를 사용하세요 — 실제 기기에서 스크린샷 테스트는 Device Farm(AWS Device Farm)을 통해서만 작동합니다.
베이스라인 관리 — 베이스라인 스크린샷은 저장소(Git LFS) 또는 S3에 저장됩니다. 각 스크린샷은 템플릿에 따라 이름이 지정됩니다: {testName}_{device}_{orientation}_{locale}.png. 예: loginScreenPixel7PortraitRu.png. 새 기기 또는 로캘을 추가할 때 새 베이스라인이 생성됩니다. UI를 변경할 때 코드 검토 후 이전 베이스라인이 새 것으로 교체됩니다. 베이스라인은 테스트 소스와 마찬가지로 코드 베이스의 일부입니다.
CI 파이프라인 — (1) 애플리케이션 빌드. (2) 에뮬레이터/시뮬레이터에서 스크린샷 테스트 실행. (3) 스크린샷을 베이스라인과 비교. (4) 불일치 시 — diff 이미지 생성. (5) diff 아티팩트 업로드(actual, expected, diff — 세 파일). (6) 결과 테이블이 포함된 HTML 보고서 게시. (7) 임계값 초과 시 — 테스트 실패. (8) 검토자가 diff 아티팩트를 검토하고 결정: 승인(베이스라인 업데이트) 또는 거부(코드 수정).
임계값 및 허용 오차 — 절대 픽셀 단위 비교는 너무 엄격합니다. SSIM(구조적 유사성 지수) 또는 MSE(평균 제곱 오차)를 사용하세요. SSIM 0.98 = 98% 구조적 유사성 — 좋은 임계값입니다. 화면에 따라 다른 임계값이 필요할 수 있습니다: 어두운 테마(검은색이 많음 — 정확도 높음), 그라데이션(노이즈 많음 — 정확도 낮음). 매개변수를 통해 테스트별로 임계값을 설정하세요: @ScreenshotTest(threshold = 0.99).
Device Farm vs 시뮬레이터 — 실제 기기에서의 테스트(Firebase Test Lab, AWS Device Farm)는 최대 현실성을 제공하지만 느리고 유료입니다. 시뮬레이터/에뮬레이터에서의 테스트는 빠르고 무료이지만 실제 기기 기능(다른 GPU, 디스플레이 색상 재현, 픽셀 밀도)을 보여주지 않습니다. 전략: 사전 병합 확인에는 시뮬레이터(5분), 야간에는 Device Farm(30분, 20개 기기). IT Sectr에서는 상위 10개 Android 기기에서 야간 실행에 Firebase Test Lab을 사용합니다.
자주 묻는 질문
Golden Test — 각 커밋에서 개별 UI 구성 요소를 빠르게 확인(50-200ms). Screenshot Test — 릴리스 전 실제 기기에서 전체 화면의 E2E 확인(2-30초). 둘 다 사용하세요: Design System 구성 요소에는 골든, 중요한 사용자 경로에는 스크린샷. 대부분의 프로젝트에서 80/20 비율이 최적입니다.
SSIM 0.98은 대부분의 화면에 적합한 시작 임계값입니다. 어두운 테마의 경우 0.99를 사용할 수 있습니다(대비가 높음 — 더 정확한 비교). 그라데이션과 이미지가 있는 화면의 경우 0.95-0.97. 절대 픽셀 단위 비교(MSE = 0)는 사용하지 마세요 — 앤티앨리어싱 및 GPU 차이로 인해 20-30%의 오탐지가 발생합니다. 각 테스트마다 개별적으로 임계값을 설정하세요.
의도적인 UI 변경이 있을 때마다 — 색상, 글꼴, 여백, 아이콘 변경, 요소 추가/제거. 환경이 변경될 때(OS 버전, CI의 글꼴)는 베이스라인을 업데이트하지 마세요 — 이는 불안정한 테스트의 징후입니다. 베이스라인은 코드 검토 후 개발자가 로컬에서만 업데이트합니다: 이전 베이스라인 삭제, record=true로 테스트 실행, 새 스크린샷 확인, 커밋.
네 — Android에서는 Espresso, iOS에서는 XCUITest를 통해 가능합니다. Espresso는 애플리케이션 프로세스 내에서 작동하며 Accessibility Service(UI Automator와 같은)가 필요하지 않습니다. XCUITest는 Apple의 표준 UI 테스트 프레임워크입니다. 스크린샷 테스트의 경우 차이는 미미합니다: XCUITest가 약간 더 안정적(네이티브 Apple API)이고, UI Automator가 약간 더 유연합니다(프로세스 간 상호 작용).
올바르게 구성된 경우 — 아닙니다. 사전 병합: 변경된 화면에서만 스크린샷 테스트를 실행합니다(30-60초). 야간: Device Farm에서 전체 실행(30분, 20개 기기). 에뮬레이터에서 스크린샷 테스트 실행 시간: 화면당 2-10초. 20개 화면 = 40-200초. 이는 한 화면의 수동 테스트 시간(5-10분)보다 적습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.