수동 테스트 과정을 건너뛰기: TesterArmy를 활용한 Expo 앱을 위한 에이전트 기반 CI
요약
본 글은 TesterArmy를 활용하여 Expo 앱의 CI(지속적 통합) 과정을 개선하는 방법을 다룹니다. 기존의 고정된 테스트 목록 대신, 에이전트 기반 CI는 풀 리퀘스트별로 적응하며 실제 사용자가 상호작용하는 것처럼 테스트를 수행합니다. 이를 통해 수동 테스트 과정 없이도 높은 수준의 품질 검증이 가능해집니다.
핵심 포인트
- 에이전트 기반 CI(Agentic CI)가 PR별로 적응하여 테스트를 진행합니다.
- TesterArmy는 시뮬레이터에서 실제 사용자의 클릭 흐름을 결정하고 테스트합니다.
- EAS Workflows를 활용하여 네이티브 빌드를 건너뛰고 속도를 최적화할 수 있습니다.
- 기존 e2e 프레임워크와 함께 사용하여 통합적인 테스트 환경을 구축할 수 있습니다.
This is a guest post from Oskar Kwaśniewski, CTO and co-founder of TesterArmy, where agents test mobile apps, web apps and websites like real users.
풀 리퀘스트(pull request)가 2일 동안 대기열에 머물러 있습니다. 변경 사항(diff)은 작고 설명도 명확하지만, 아무도 시뮬레이터를 열어 변경된 화면을 직접 터치하며 테스트할 시간이 없습니다. 결국 어쨌든 병합되고, 실제로 그 흐름을 사용해 보는 첫 번째 사람은 프로덕션 환경의 사용자입니다.
지난주 Expo는 EAS Workflows 내부에 에이전트를 배치했을 때 어떤 일이 발생하는지를 보여주었습니다.
일반적인 CI(지속적 통합)는 고정된 목록을 실행합니다. 풀 리퀘스트가 발생할 때마다 변수 이름을 변경했든, 온보딩 과정을 새로 작성했든 상관없이 동일한 작업들을 같은 순서로 트리거합니다. 에이전트 기반 CI(Agentic CI)란 이 목록이 풀 리퀘스트별로 적응한다는 것을 의미합니다. EAS Workflows는 앱을 빌드하고, 자바스크립트만 변경된 경우 마지막 네이티브 빌드를 재사용합니다. TesterArmy 에이전트는 풀 리퀘스트를 읽고 시뮬레이터에서 실제로 어떤 부분을 클릭할지 결정합니다.
현재 TesterArmy는 물리적 기기(실제 장치 지원은 곧 제공될 예정)가 아닌 클라우드 iOS 시뮬레이터와 안드로이드 에뮬레이터에서 실행됩니다. 이미 가지고 있는 어떤 e2e 프레임워크와도 함께 실행할 수 있습니다.
파트 1: 에이전트가 워크플로우를 작성해 드립니다
파트 2: EAS가 앱을 빌드하고 건너뛸 수 있는 부분
기본 워크플로우는 main 브랜치에 푸시되거나, main으로 향하는 풀 리퀘스트(pull requests) 또는 workflow_dispatch 시 트리거됩니다. 이 워크플로우는 iOS Simulator 앱과 Android APK를 빌드하고, 각각의 아티팩트를 eas/download_build로 다운로드한 다음, TesterArmy에 업로드하여 플랫폼별로 저장된 테스트 그룹을 실행합니다. 여기서 시작하세요. 매번 전체 네이티브(native) 빌드를 수행하는 것은 속도가 느리지만, 설정을 연결하는 동안 변수를 제거해 줍니다.
이 부분이 안정화되면, EAS가 가능한 경우 네이티브 빌드를 건너뛰도록 하세요. Expo의 fingerprint 작업은 네이티브 런타임에 해시(hash)를 적용합니다. get-build 작업은 해당 해시로 기존 빌드가 있는지 확인합니다. 만약 존재한다면, repack 작업은 앱의 메타데이터와 JavaScript 번들을 그 위에 다시 패키징할 뿐이며, 전체 네이티브 재빌드는 필요하지 않습니다. 일치하는 빌드가 없으면 정상적인 빌드로 폴백(fallback)됩니다.
jobs:
fingerprint:
name: Calculate app fingerprints
...
Android 부분은 APK 프로필로 이를 반영합니다. upload 작업은 repack 또는 build 중 어느 것이든 build_id를 생성한 후에 실행됩니다. Expo 자체 문서를 따른 주의사항이 하나 있습니다. fingerprint 작업은 CNG 프로젝트용으로 빌드되었습니다. 만약 android 또는 ios 디렉토리를 직접 커밋하면 작동하지 않으므로, 기본 워크플로우를 유지하세요.
이 부분이 실제로 루프(loop)를 짧게 유지하는 부분입니다. 네이티브 빌드는 모든 EAS 워크플로우에서 느린 단계이며, 성숙한 Expo 앱의 대부분의 풀 리퀘스트는 JavaScript만 건드립니다. repack을 사용하면, 네이티브 빌드는 런타임 변경당 한 번만 발생하며, 다른 모든 풀 리퀘스트는 바로 repack에서 upload를 거쳐 테스트로 넘어갑니다.
파트 3: 에이전트가 무엇을 테스트할지 알아냅니다
모든 PR에 대한 회귀 테스트(Regression tests)는 이전에 작동했던 것을 망가뜨리지 않았음을 확인시켜 줍니다. 여기서 새로워진 것은 풀 리퀘스트에서만 실행되고, 동일하게 업로드된 빌드를 대상으로 하여 자체적인 테스트 계획을 수립하는 작업입니다.
이것은 파일을 읽고 diff를 분석하여 변경의 의도를 파악하고, 해당 변경에 특화된 자연어 순서 목록을 작성하며, 시뮬레이터에서 이를 실행한 후 GitHub 체크와 풀 리퀘스트 댓글을 게시합니다. 이 댓글은 먼저 계획된 단계를 표로 보여주고, 이후 단계별 결과로 제자리에 업데이트됩니다. 모든 실행에는 비디오가 첨부됩니다.
run_ios_dynamic_agent:
name: Run iOS TesterArmy dynamic agent
needs: [upload_ios_app]
...
이 기능을 사용하기 전에 알아야 할 두 가지 동작 방식이 있습니다.
첫째, 스킵 판단기(skip judge)는 어떤 작업도 실행되기 전에 diff를 읽습니다. 만약 풀 리퀘스트가 사용자에게 보이는 변화가 없다면 (문서 편집, 설정 파일 업데이트 등), 해당 실행은 건너뛴 것으로 보고되고, 체크에는 이유와 함께 "테스트 건너뜀(Tests skipped)"로 표시되며 작업은 성공합니다. 모바일 환경에서는 판단기가 플랫폼별로 결정하므로, iOS 전용 변경이라도 iOS에서는 테스트가 진행되는 반면 Android 실행은 건너뛰어집니다. 일단 판단기가 테스트를 수행하기로 결정하면, 해당 실행은 항상 실행됩니다.
둘째, 실제 실패는 EAS 작업을 실패시키지만, GitHub 체크는 기본적으로 권고(advisory) 사항입니다. 실패한 실행은 중립(neutral)으로 결론지어지며, GitHub는 중립을 성공으로 간주합니다. 만약 테스트 실패가 실제로 병합을 차단하도록 하려면, 프로젝트의 PR Testing 탭에서 "테스트 실패 시 병합 차단(Block merges on failed tests)\
이것으로 루프가 완성됩니다. 코딩 에이전트가 변경 사항과 지침을 작성하고, EAS가 빌드하거나 리패킹합니다. 테스트링 에이전트는 이 지침과 diff를 바탕으로 계획을 세우고, 앱을 탐색하며, 풀 리퀘스트에 비디오를 남깁니다. 아무도 테스트 스크립트를 직접 작성하지 않습니다.
하루 50개의 풀 리퀘스트에서 이것이 어떻게 작동하는가
Juno는 React Native와 Expo를 사용하여 만성 질환을 앓는 사람들을 위한 건강 비서 앱을 iOS 및 Android용으로 구축합니다. 일곱 명의 사람이 매주 한두 번 업데이트를 배포하며, 이는 그들 입장에서 하루에 50개에서 100개의 풀 리퀘스트를 의미합니다.
모든 풀 리퀘스트는 온보딩, 증상 기록, 약물 복용, 알림, 결제벽(paywall), 계정 흐름 등 양 플랫폼 전반에 걸쳐 각각 약 5분씩 총 6번의 TesterArmy 실행을 거칩니다. 이러한 흐름은 선택자(selectors)가 아닌 일반 언어 사용자 여정으로 작성됩니다. 이 팀은 2026년 7월에 501개의 풀 리퀘스트를 병합했고, 8월에는 791개를 병합했습니다. Juno의 공동 창업자이자 CEO인 Marshall Gould는 제가 말하는 것보다 더 직설적으로
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기