본문으로 건너뛰기
중급약 40분

디바이스 팜 실습 — Firebase Test Lab·BrowserStack 으로 매트릭스 돌리기

기기를 몇 대 살까가 아니라 어떤 조합을 왜 고르는가가 실력이다. 사용자 통계로 커버리지 목표를 세워 기기 매트릭스를 근거 있게 뽑고, Firebase Test Lab의 Robo·계측 테스트와 BrowserStack의 수동·자동 실행을 목적에 맞게 나눠 쓰며, 비디오·logcat·성능 지표로 결과를 판독한다. 병렬 실행과 비용의 균형, 실기기와 에뮬레이터의 파이프라인 단계별 배치까지 정리한다.

  • #디바이스팜
  • #FirebaseTestLab
  • #BrowserStack
  • #커버리지매트릭스
  • #Robo테스트

개념

이 레슨이 앞 레슨들과 갈라지는 지점

모듈 13 레슨 8에서 조합 폭발과 우선순위 매트릭스를, 모듈 17 레슨 5에서 실기기와 에뮬레이터의 성질 차이를 다뤘다. 둘 다 판단 기준 을 세우는 레슨이었다. 이 레슨은 그 기준을 클라우드 팜에서 실제로 도는 실행 계획 으로 바꾼다 — 어떤 도구에 무엇을 맡기고, 결과 화면에서 무엇을 읽고, 비용이 어디서 새는가.

매트릭스는 "근거"가 붙어야 매트릭스다

"갤럭시 최신폰이랑 아이폰 하나 있으면 되겠죠?"는 매트릭스가 아니다. 매트릭스는 커버리지 목표 → 축 선정 → 조합 선택 → 잔여 위험 명시 라는 네 단계를 거쳐 나온 문서이고, 각 단계에 숫자나 근거가 붙어 있어야 팀이 합의할 수 있다.

1단계 — 커버리지 목표를 숫자로 정한다. "활성 사용자의 몇 %를 검증된 조합 위에서 돌게 할 것인가"를 먼저 합의한다. 흔한 형태는 "상위 조합으로 MAU의 80%를 덮고 나머지는 크래시 모니터링으로 사후 감시한다"이다. 이 한 줄이 "왜 이 기기는 안 샀냐"에 대한 답이 된다.

2단계 — 축을 고른다. 기기 이름은 축이 아니다. 축은 결함을 만들어 내는 변수 다.

축왜 결함을 만드는가대표 선택
OS 메이저 버전권한·백그라운드·알림 정책이 버전마다 바뀐다최신, 최신-1, 그리고 사용자 비중이 큰 구버전
화면 크기·종횡비·노치레이아웃 깨짐, 잘림, 세이프 에어리어소형·표준·대형, 폴더블 1대
메모리·칩셋 등급저사양에서만 나오는 ANR·OOM·프레임 드랍상위 1, 보급형 1
제조사 ROM절전 정책·알림 정책이 표준과 다르다(레슨 3)국내 주력 제조사 + 중국계 ROM 1
화면 밀도·글꼴 배율접근성 설정에서의 레이아웃 붕괴(레슨 6)고밀도 1대에서 배율 축 추가

3단계 — 조합을 고른다. 축을 전부 곱하지 않고 각 축의 값이 최소 한 번씩은 등장하도록 고른다(페어와이즈에 가까운 사고방식이다). 보통 8~12대면 목표 커버리지에 닿는다.

4단계 — 잔여 위험을 남긴다. "폴더블 미검증", "Android 10 이하 미검증, 사용자 2.1%" 처럼 덮지 못한 부분을 이름 붙여 적는 것 이 매트릭스의 절반이다. 사고가 났을 때 "몰랐다"와 "알고 감수했다"는 완전히 다른 문서다.

사용자 통계를 어디서 가져오는가

근거는 우리 서비스의 실제 사용자 데이터 여야 한다. 시장 점유율 기사는 참고일 뿐이다. Google Play Console 의 기기 카탈로그·통계에서 설치·활성 기기를 모델·Android 버전·RAM·화면 크기별로 볼 수 있고, App Store Connect 앱 분석에서 기기·iOS 버전 분포를 본다. Firebase Analytics·Crashlytics 는 사용자 분포와 크래시가 몰리는 기기 를 함께 보여 주는데, 크래시가 집중된 기기는 사용자 비중과 무관하게 매트릭스에 넣는다.

표는 이렇게 만든다. 누적 비율 열이 있어야 "어디서 끊을지"를 정할 수 있다.

순위기기 · OS비중누적매트릭스 포함사유
1Galaxy S24 / Android 1414.2%14.2%포함최다 사용
2iPhone 15 / iOS 1811.8%26.0%포함iOS 최다
3Galaxy A34 / Android 139.1%35.1%포함보급형 대표(저메모리 축)
…
11Galaxy Z Flip5 / Android 141.3%81.4%포함폴더블 축 단독 커버
—Android 10 이하 합계2.1%—제외잔여 위험으로 기록

11위 기기가 비중 1.3%인데 포함된 이유가 "폴더블 축을 다른 기기가 덮지 못해서"라는 점이 중요하다. 비중 순서로만 자르면 축이 빈다.

Firebase Test Lab — 무엇에 쓰는 도구인가

Google이 운영하는 기기 팜이다. 구글 데이터센터의 실제 물리 기기 와 Arm 호스트에서 도는 가상 Android 기기 를 함께 제공하며 Android·iOS 앱을 모두 돌린다. 지원 테스트 유형은 네 가지다.

유형사전 스크립트무엇을 확인하나
Robo 테스트(Android)필요 없음크롤러가 UI를 자동 탐색하며 크래시·ANR을 찾는다
계측 테스트(Android)Espresso·UI Automator 등으로 작성우리가 쓴 단언(assertion)을 여러 기기에서 검증
XCTest(iOS)XCTest로 작성iOS 쪽 단언 검증
Game Loop(Android·iOS)게임 내 루프 구현게임의 반복 구간을 자동 주행

QA 실무에서 갈리는 지점은 Robo 테스트와 계측 테스트의 역할 분담 이다.

  • Robo 는 "공짜로 얻는 스모크"다. 테스트 코드 없이 새 빌드를 여러 기기에 올려 "켜지는가, 돌아다니다 죽지 않는가"를 확인한다. 기기별 크래시·ANR을 싸게 발견하는 데 탁월하다
  • Robo 는 검증이 아니다. 크롤러는 "금액이 12,000원이어야 한다"를 판정하지 못하고, 로그인 벽을 넘지 못하는 경우도 많다(자격 증명 주입 설정이 있지만 흐름이 복잡하면 못 넘는다). 정답 여부는 계측 테스트나 사람이 본다
  • 둘을 같은 매트릭스에 동시에 올린다. Robo는 전체 기기에, 계측은 핵심 기기 몇 대에 — 비용과 신호의 균형이 여기서 나온다

CI에는 gcloud CLI로 붙인다.

gcloud firebase test android models list          # 사용 가능한 모델·버전
gcloud firebase test android run \
  --type instrumentation --app app-debug.apk --test app-debug-androidTest.apk \
  --device model=<모델ID>,version=<API레벨>,locale=ko,orientation=portrait \
  --device model=<모델ID>,version=<API레벨>,locale=ko,orientation=landscape \
  --timeout 20m

--device 를 여러 번 쓰면 조합이 늘고 기기 수만큼 요금과 시간이 곱해진다. 매트릭스 문서의 조합을 그대로 이 플래그로 옮기면 문서와 실행이 어긋나지 않는다.

BrowserStack — 무엇이 다른가

BrowserStack은 구독형 상용 기기 클라우드다. App Live 는 원격 실기기를 브라우저로 직접 조작하게 해 준다 — 탐색적 테스트, 재현 확인, 고객이 보고한 특정 기종 이슈를 그 기종에서 만져 보는 용도다. App Automate 는 Appium·Espresso·XCUITest 스크립트를 실기기에서 병렬로 돌리고, 세션마다 비디오·기기 로그·네트워크 로그를 남긴다.

Test Lab과의 실질적 차이를 정리해 두면 도구 선택 회의가 짧아진다.

관점Firebase Test LabBrowserStack
강점테스트 코드 없이 돌리는 Robo, Google 생태계·CI와의 결합기기·OS 선택 폭, 사람이 직접 만지는 원격 실기기
과금사용량 기반(기기·시간)좌석/병렬 세션 기반 구독
수동 탐색사실상 불가App Live가 핵심 기능
주 용도CI에서 자동으로 도는 회귀·스모크 매트릭스재현·탐색·특정 기종 대응, 그리고 자동화 병렬 실행

두 서비스의 지원 기기 목록·요금 체계·무료 할당량은 수시로 바뀐다. 이 레슨은 구조 만 설명한다. 실제 숫자는 각 서비스의 가격·할당량 문서에서 원문 확인 한다.

현실적인 조합은 "CI 회귀는 Test Lab, 재현과 탐색은 BrowserStack"이다. 하나만 쓸 수 있다면 팀이 자동화 테스트를 이미 갖고 있는지 로 가른다 — 없으면 Robo와 App Live 쪽 가치가 크고, 있으면 병렬 실행 능력이 값을 한다.

실행 결과를 읽는다 — 여기가 실습의 핵심이다

매트릭스를 돌리는 것은 쉽다. 어려운 것은 빨간 줄 30개를 보고 실제 결함이 몇 개인지 판정하는 일 이다. 순서를 고정한다.

1. 먼저 묶는다. 같은 예외 메시지·같은 화면에서 실패한 것을 한 덩어리로 본다. 기기 10대에서 난 실패가 사실 원인 하나인 경우가 흔하다.

2. "기기 고유인가"를 가른다. 같은 테스트가 특정 OS 버전에서만, 특정 제조사에서만, 특정 해상도에서만 실패하면 축이 원인이다. 전 기기에서 실패하면 기기 문제가 아니라 코드·환경 문제다.

3. 비디오와 스크린샷을 본다. 로그보다 빠르다. 실패 직전 몇 초를 보면 "권한 팝업이 떠서 탭이 막혔다", "광고 배너가 버튼을 덮었다", "폰트가 커져 버튼이 화면 밖으로 나갔다" 같은 원인이 바로 보인다. 이 부류는 제품 결함이 아니라 테스트 결함 인 경우도 많다.

4. 로그를 본다. Android는 logcat, iOS는 기기 로그다. 크래시 스택, ANR 직전 메인 스레드 상태, 네트워크 타임아웃이 여기 있다.

5. 성능 지표를 본다. 실행 중 CPU·메모리·네트워크·프레임 지표가 함께 기록된다. 저사양 기기에서만 나는 실패는 거의 항상 여기에 설명이 있다.

6. 재실행으로 불안정을 가른다. 같은 기기에서 다시 돌려 통과하면 불안정(flaky) 후보다. 모듈 13 레슨 6의 원칙대로 불안정 목록을 따로 관리 한다.

판정 결과는 이런 표로 남긴다.

증상재현 기기미재현 기기판정조치
결제 화면 진입 시 ANR보급형 2대(4GB)상위 3대결함(저메모리)성능 티켓, 메모리 프로파일 첨부
로그인 탭 실패전 기기 1회차2회차 전부 통과불안정(대기 부족)테스트 코드 수정
하단 버튼 잘림소형 1대나머지결함(레이아웃)UI 티켓, 스크린샷 첨부

병렬 실행과 비용

클라우드 팜의 요금은 대체로 기기 × 시간 으로 붙는다. 그래서 비용 관리의 핵심은 "얼마나 많이 도는가"가 아니라 "얼마나 오래 점유하는가" 다.

  • 샤딩(분할) 은 전체 소요 시간을 줄이지만 총 기기-분은 줄이지 않는다. 시간을 사는 것이지 비용을 아끼는 것이 아니라는 점을 팀에 정확히 말한다
  • 타임아웃을 반드시 건다. 멈춘 테스트가 기기를 최대 시간까지 붙잡는 것이 가장 비싼 실수다
  • 계층을 나눈다. PR마다 가상 기기 2~3대 스모크, 야간에 실기기 핵심 매트릭스, 릴리스 후보에만 전체 매트릭스
  • 재시도는 1회로 제한하고, 재시도로 통과한 것은 불안정 목록에 넣는다. 무한 재시도는 비용을 조용히 태운다

실기기와 에뮬레이터를 어디에 쓰는가

모듈 17 레슨 5에서 둘의 성질 차이를 배웠다. 여기서는 그것을 파이프라인 단계에 배치 한다.

단계환경이유
로컬 개발·PR 검증로컬 에뮬레이터 / 가상 기기빠르고 싸다. 로직·화면 전환 회귀에 충분
야간 회귀클라우드 실기기 핵심 5~8대 + 가상 기기 다수기기 고유 문제를 매일 감시하되 비용은 통제
릴리스 후보전체 매트릭스(실기기 중심)출시 전 마지막 관문
탐색·재현손에 잡히는 실기기 또는 App Live사람이 만져야 보이는 것들

에뮬레이터·시뮬레이터가 구조적으로 못 잡는 것 은 목록으로 외워 둔다. 이것이 "왜 실기기가 필요한가"에 대한 답이다.

  • 카메라·지문·얼굴인식 등 하드웨어 센서 와 생체 인증 흐름
  • 실제 성능 — 발열로 인한 성능 저하, 저사양 기기의 프레임·메모리 압박
  • 배터리 소모 와 제조사 ROM의 절전·알림 정책(레슨 3에서 본 그 문제)
  • 통신사 네트워크 — 셀룰러 전환, 약한 신호, 통화 인터럽트
  • 결제·NFC 등 보안 하드웨어가 개입하는 흐름, 그리고 터치 정확도·햅틱 같은 물리적 감각

반대로 에뮬레이터가 나은 것도 있다. 화면 크기·밀도·글꼴 배율·로케일을 마음대로 바꿔 가며 레이아웃 회귀를 훑는 작업, 네트워크 상태를 인위적으로 만드는 작업, 수십 개 조합을 빠르게 병렬로 도는 작업이다. "실기기가 항상 우월하다"는 틀린 말이다 — 무엇을 검증하려는가에 따라 갈린다.

실무에서 왜 필요한가

기기 예산은 언제나 부족하고, 그 부족함을 메우는 것이 QA의 설계 능력이다. "기기 10대 사 주세요"라는 요청은 통과되기 어렵지만, "MAU 81%를 덮는 11개 조합이고, 이 중 4대는 클라우드로 대체 가능하며, 덮지 못하는 2.1%는 이런 위험을 감수하는 것"이라는 문서는 통과된다. 매트릭스는 테스트 산출물이면서 동시에 예산 협상 문서 다.

결과 판독 능력은 더 직접적으로 시간을 아낀다. 팜을 도입한 팀이 실패하는 이유는 도구가 나빠서가 아니라 매일 아침의 빨간 줄 수십 개를 아무도 읽지 않게 되어서다. 묶고 · 축으로 가르고 · 비디오를 먼저 보는 순서 하나만 정착시켜도 팜은 살아난다.

채용시장에서의 위치

"디바이스 커버리지를 어떻게 정하셨나요"는 모바일 QA 경력 면접의 표준 질문이다. 기기 이름을 나열하면 평범하고, 커버리지 목표 숫자 → 축 → 잔여 위험 문서화 로 답하면 설계를 해 본 사람으로 읽힌다. 여기에 "Robo는 전 기기, 계측은 핵심 기기"처럼 비용과 신호를 저울질한 경험, 그리고 불안정을 결함과 분리해 관리한 경험을 덧붙이면 자동화 조직에서도 바로 받아들여진다. 커버리지 매트릭스 문서 한 장은 포트폴리오로도 강하다.

실습 과제

과제 1 — 근거 있는 기기 매트릭스 설계 (30분)

자신이 맡은(또는 임의로 정한) 서비스의 사용자 분포를 가정하거나 실제 데이터로 가져와, 본문의 4단계를 따라 매트릭스를 만든다.

  1. 커버리지 목표를 한 문장으로 적는다 (예: "MAU 80% 이상을 검증 조합으로 덮는다")
  2. 축 표를 채운다 — OS 버전, 화면, 메모리 등급, 제조사 ROM, 글꼴 배율
  3. 누적 비율 열이 있는 기기 표를 만들고, 목표에 닿는 지점에서 자른다
  4. 축이 비는 곳을 확인해 추가 기기를 넣고, 그 사유를 적는다
  5. 덮지 못한 구간을 "잔여 위험" 항목으로 이름 붙여 남긴다

완성된 표를 보고 "이 기기는 왜 포함됐나"에 전부 한 줄로 답할 수 있으면 통과다.

과제 2 — Robo 테스트와 계측 테스트의 역할 나누기 (25분)

아무 앱이나 하나를 대상으로, 핵심 사용자 흐름 5개를 적고 각각에 대해 Robo 테스트가 커버할 수 있는가 / 계측 테스트가 필요한가 / 사람이 봐야 하는가 를 판정한다. 판정 근거를 한 줄씩 적는다. 실행 환경이 있다면 실제로 Robo 를 한 번 돌려 본다.

gcloud firebase test android run --type robo --app <APK> \
  --device model=<모델ID>,version=<API레벨>,locale=ko --timeout 5m

돌렸다면 결과 화면에서 (a) 크롤러가 실제로 도달한 화면, (b) 도달하지 못한 화면과 그 이유, (c) 발견된 크래시·ANR 유무를 정리한다. 도달하지 못한 화면이 곧 계측 테스트나 사람이 맡아야 할 범위 다. 실패가 나왔다면 본문의 판정 표 형식으로 결함 / 불안정 / 테스트 결함 / 환경 문제 중 하나로 분류해 본다.

자가 체크리스트

  • 커버리지 목표를 숫자로 정하고 그것으로 기기 선정을 방어할 수 있다
  • 기기 이름이 아니라 결함을 만드는 축으로 매트릭스를 설계할 수 있다
  • Play Console·App Store Connect·Crashlytics에서 근거 데이터를 어디서 보는지 안다
  • 비중이 낮아도 축을 단독으로 덮는 기기를 포함시키는 판단을 할 수 있다
  • 덮지 못한 조합을 "잔여 위험"으로 문서에 남길 수 있다
  • Robo 테스트와 계측 테스트의 역할을 나누고 비용·신호를 설명할 수 있다
  • Firebase Test Lab과 BrowserStack의 강점 차이와 주 용도를 구분할 수 있다
  • 실패 묶음을 축으로 가르고 비디오·로그·성능 지표 순으로 판독할 수 있다
  • 샤딩이 시간을 줄이지 비용을 줄이지는 않는다는 점을 설명할 수 있다
  • 파이프라인 단계별로 실기기와 가상 기기를 배치하고 근거를 댈 수 있다

흔한 실수

  • 비중 순서로만 잘라 축을 비운다. 상위 10대가 전부 상위 기종이면 저메모리·소형 화면·폴더블 결함이 통째로 미검증으로 남는다. 자른 뒤 축 표를 다시 대조한다.
  • 일반 시장 점유율 기사를 근거로 쓴다. 우리 서비스의 사용자 분포는 시장 평균과 다르다. Play Console·App Store Connect의 자기 데이터를 쓴다.
  • Robo 테스트를 기능 검증으로 믿는다. 크롤러는 "초록"을 주지만 값이 맞는지는 모른다. Robo 통과를 회귀 통과로 보고하면 안 된다.
  • 모든 빌드를 전체 매트릭스에 올린다. 비용과 대기 시간이 함께 터지고, 결국 아무도 결과를 안 본다. PR·야간·릴리스 3계층으로 나눈다.
  • 타임아웃 없이 돌린다. 멈춘 세션 하나가 최대 시간만큼 기기를 점유한다. 모든 실행에 타임아웃을 건다.
  • 실패를 전부 결함으로 올린다. 불안정과 테스트 결함이 섞이면 개발팀이 결과를 무시하기 시작한다. 판정 표로 분류한 뒤 올린다.
  • 실기기만이 정답이라고 말한다. 레이아웃·로케일·글꼴 배율 회귀는 가상 기기가 더 빠르고 싸다.

참고 자료

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

OS — 운영체제
기기를 돌리는 바탕 프로그램 — 윈도우, 맥, 안드로이드 같은 것.
OOM — 메모리 부족
쓸 수 있는 메모리를 다 써서 프로그램이 죽는 상황.
UI — 사용자 인터페이스
사람이 직접 보고 누르는 부분 — 화면, 버튼, 입력창.
QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.
CI — 지속적 통합
코드를 올릴 때마다 자동으로 합쳐서 빌드하고 시험까지 돌리는 방식.
CLI — 명령 줄 인터페이스
검은 화면에 글자로 명령을 적어 넣는 방식. 버튼은 없고 줄마다 명령을 쓴다.
CPU — 중앙처리장치
계산을 담당하는 부품. 사람으로 치면 머리다.
PR — 풀 리퀘스트
"내가 고친 코드를 본체에 합쳐 달라"고 올리는 요청. 합치기 전에 사람들이 보고 의견을 단다.

용어집 전체 보기