토스가 각 팀이 각자 운영하던 작은 디바이스 팜을 하나의 중앙 플랫폼 '네뷸라(Nebula)'로 통합한 과정을 다룬다. Appium 대신 자체 드라이버를 개발해 클릭 13.5배, 텍스트 입력 10배의 성능을 달성했고, Android와 iOS 미러링도 직접 내재화해 실기기 원격 조작과 화면 실시간 공유를 동시에 가능하게 만들었다. 현재 100대를 넘어 수백 대를 향해 24시간 가동 중이다.
핵심 포인트- 팀마다 맥북에 폰 5~10대를 꽂아 각자 운영하던 분산 팜을 단일 중앙 플랫폼으로 통합, API 호출 한 번으로 실기기 제어
- Appium 대비 클릭 13.5배(52ms vs 702ms), 텍스트 입력 10배(138ms vs 1,377ms) 빠른 자체 Nebula Driver 개발
- Appium의 세션 기반 구조(시작 15~40초) → stateless HTTP + pre-warm 컨트롤러로 전환
- Android는 SurfaceControl+MediaCodec H.264, iOS는 QuickTime 캡처 경로 내재화로 60~120fps 미러링 + 조작 공존
- 중앙화로 보안 정책 일괄 적용, 자체 IME·앱센터 연동·커스텀 신호 등 토스 앱 전용 기능 탑재
- AI 에이전트 기반 테스트 자동 구축, 테스트 조건 빠른 프로비저닝을 다음 목표로 설정
상세 정리- 배경: 각 팀이 맥북·맥미니에 폰 5~10대를 꽂아 Appium 팜을 각자 운영. 세팅 진입장벽, 중복 삽질, 기기 격리, 보안 각자 관리 등 비효율
- 목표 설정: 누구든 API 호출 한 번으로 실기기 제어 — POST /device/occupy 로 기기 점유, POST /actions/click 으로 조작
- 아키텍처 4계층: 클라이언트(웹UI/SDK/CLI/API) → 서버(Kafka 큐, 분산 락) → 에이전트(호스트 프로세스, ADB/Xcode) → 기기(컨트롤러 서버+러너)
- Appium 한계: 세션 시작 15~40초, 규모 커질수록 세션 실패 잦음, 세션 관리 비용 증가
- Nebula Driver 성능: 클릭(id find+click) 52ms vs Appium 702ms(13.5배), 텍스트 입력 138ms vs 1,377ms(10배)
- Stateless 전환: 기기 컨트롤러 상시 pre-warm 후 상태 없는 HTTP 호출로 세션 제거, 대기 시간 0
- 커스텀 기능: 자체 한글·이모지 IME, 토스 앱 전용 신호 트리거, 앱센터(pre-release 빌드) 직접 설치 연동
- Android 미러링: SurfaceControl 가상 디스플레이 생성 → MediaCodec H.264 인코딩 → 브로드캐스터로 다중 브라우저 스트리밍
- iOS 미러링 문제: QVH는 USB 독점으로 조작 불가, Appium MJPEG는 10~15fps 끊김
- iOS 미러링 해결: QuickTime 캡처 장치를 USB 독점 없이 활용하는 방식 내재화 → 60~120fps + 조작 공존
- 보안: 분산 운영 시절엔 팀마다 보안 기준이 달랐으나, 중앙화 후 보안팀 기준을 모든 기기에 일괄 적용
- 운영 안정성: USB 케이블·허브·전원 설계, 프로세스 오케스트레이션, 무중단 배포, 모니터링 구축 중
- 현황: 15대 → 100대+ 가동, 수백 대 증설 중. 웹UI/SDK/CLI/AI에이전트/로그검수 시스템으로 소비
- 실사용 사례: Appium 대비 회귀테스트 부담 제거, 30~40분 수동 검수 → 10분 자동 검증
왜 읽나모바일 E2E 자동화 인프라를 직접 구축하거나 Appium의 성능·확장 한계에 부딪힌 QA·모바일·플랫폼 엔지니어에게 실전 아키텍처·성능 수치 레퍼런스.