Github Action과 self-hosted runner로 구축하는 E2E 테스트 자동화: POC부터 확장까지 우리팀의 내재화 여정
안녕하세요. 펫프렌즈 모바일 플랫폼 팀에서 iOS 앱 개발을 담당하고 있는 넬로입니다.
Github Action과 self-hosted runner로 구축하는 E2E 테스트 자동화: POC부터 확장까지 우리팀의 내재화 여정

소개
안녕하세요.
펫프렌즈 모바일 플랫폼 팀에서 iOS 앱 개발을 담당하고 있는 넬로입니다.
이전 포스팅에서는 iOS 앱에서 웹뷰(WKWebview) UI 테스트를 Appium을 활용해 구현한 과정을 소개드렸습니다.

이번 글에서는 여기서 한 걸음 더 나아가,
iOS뿐만 아니라 Android 앱역시 웹뷰 UI 테스트를 구축했었는데,
이 두 플랫폼의 테스트를 하나의 파이프라인에서 동시에 실행할 수 있도록 만든 자동화 환경과 인프라를 공유드리려고 합니다.
이 과정을 통해 iOS·Android 웹뷰 기반 앱을 모두 운영하는 환경에서,
E2E 시나리오를 병렬로 테스트하여 효율성을 올린 방법을 소개 해드리고자 작성하게 되었습니다.
웹뷰 기반 앱을 개발·운영하며 테스트 자동화를 고민하고 계신 분들께
실무적으로 도움이 되길 바랍니다.
글을 쓰게 된 배경
💡 먼저, 저희가 완벽한 시스템을 구축했다는 것은 아니며, 아직도 개선해야 할 부분이 많다는 점을 미리 말씀드립니다.
기존 상황
- 기존에 외부 테스트 서비스를 사용하여 모바일 앱 테스트를 진행
- 범용적인 서비스 특성상 사내 앱의 특수한 요구사항(웹뷰 기반, 특정 비즈니스 플로우)에 최적화되지 않은 부분들이 존재
- 비용 대비 효용성을 고민하게 되면서 내재화 필요성이 대두
현실적인 선택
- 처음부터 본격적인 사내 디바이스 팜을 구축하기에는 리소스 부족
- 그렇다고 수동 테스트로만 계속하기에는 반복 업무의 한계 명확
- “일단 해볼 수 있는 것부터” 시작해보자는 마음으로 간단한 구성으로 출발
- 사내 유휴 장비(Mac mini)를 활용해 작은 규모의 POC로 검증해보기로 결정
전체 아키텍처 개요

파이프라인 요약
각 구성요소 역할
- Slack: 사용자가 직접 테스트를 트리거할 수 있는 인터페이스
- Webhook: Slack 명령을 파싱하여 내부 GitHub Action을 호출
- GitHub Self-hosted Runner: 사내 Mac mini에 설치되어 테스트를 실제로 실행
- Appium: E2E 테스트 프레임워크로, 실제 기기를 통해 테스트 수행
- Slack 결과 보고: 테스트 성공/실패 및 주요 로그를 Slack으로 전송
Slack 커맨드로 테스트 시작하기
- Slack → Webhook → 사내 서버로 명령 전달 구조 설명
- 예시 커맨드 (
/start-scenario-tests)
구조
- 사용자가 Slack에서
/start-scenario-tests같은 명령어 입력 - Slack → Webhook URL로 요청 전송
- Express 기반 Webhook 서버가 이를 파싱하여 GitHub
workflow_dispatch이벤트 호출 - GitHub Action이 사내 Mac mini에서 동작
보안 처리
- ngrok을 통해 Webhook 서버를 외부에서 접근 가능하도록 설정
- Slack Slash Command가 내부 서버로 전달될 수 있도록 안전한 HTTPS 터널링 제공
- ngrok의 토큰 인증 및 IP 필터링 기능으로 기본적인 보안 확보
예시 커맨드
/start-scenario-tests "명령어"
Mac mini에 GitHub Self-Hosted Runner 구성
- Runner 설치 방법 및 실행 방식
- 여러 프로젝트에 대응하는 방식 (Label 기반 분기, 병렬 처리 여부 등)
- 자동 재시작 처리 (runner 중단 시 systemd or launchd 설정 등)
앱 시나리오 테스트 자동화
- 테스트 종류 (E2E, UI, 시나리오 테스트 등)
- GitHub Action 워크플로 예시
- 결과를 Slack으로 다시 전달하는 방식
테스트 범위
- E2E 테스트
- 앱 설치 → 실행 → 온보딩 → 웹뷰 전환 → 기존 수동 테스트에서 다뤘던 핵심 시나리오 검증
GitHub Actions 워크플로 예시
워크플로우를 주요 기능별로 나누어 살펴보겠습니다.
1. 자동 스케줄링
on:
workflow_dispatch: # 수동 실행
schedule:
- cron: "0 9 * * *" # 매일 오전 9시
- cron: "0 3 * * 1" # 매주 월요일 새벽 3시
정기적 자동 테스트 실행으로 회귀 버그 조기 발견이 가능합니다.
2. 매트릭스 전략 (iOS/Android 병렬 실행)
strategy:
fail-fast: false
matrix:
platform: [ios, android]
include:
- platform: ios
test_command: "pnpm run test:scenarios:ios"
- platform: android
test_command: "pnpm run test:scenarios:android"
두 플랫폼을 동시에 테스트하여 실행 시간을 단축하고, 한 플랫폼 실패 시에도 다른 플랫폼은 계속 실행합니다.
3. 테스트 실행
steps:
- uses: actions/checkout@v3
- run: pnpm install
- name: Run Tests
run: ${{ matrix.test_command }}
플랫폼별 테스트 명령어를 매트릭스 변수로 동적 실행합니다.
4. S3 리포트 업로드
- name: Upload Report
if: always()
run: |
TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
aws s3 cp ./mochawesome-report-${{ matrix.platform }}/ \\
s3://$S3_BUCKET/reports/${TIMESTAMP}/ --recursive
테스트 실패 여부와 관계없이 항상 리포트를 S3에 업로드하여 결과를 보관합니다.
5. Slack 결과 알림
- name: Notify Slack
if: always()
run: |
STATUS="${{ job.status == 'success' && '✅ 성공' || '❌ 실패' }}"
curl -X POST --data "{\\"text\\":\\"${{ matrix.platform }} 테스트 ${STATUS}\\"}" \\
$SLACK_WEBHOOK_URL
테스트 완료 후 즉시 Slack으로 결과를 알림하고, 성공/실패 상태를 구분합니다.
점진적 개선 여정
1. 최소한의 POC로 시작
초기에는 최소한의 검증을 통해 접근 방식의 타당성을 확인하는 것부터 시작했습니다.
초기 목표
- Mac mini 1대 + 실제 iOS/Android 기기 연결만으로도 기본적인 자동화가 가능한지 검증
- GitHub Actions와 Slack 연동으로 테스트 실행과 결과 알림 구현
- 외부 서비스 대신 저희만의 테스트 환경에서 웹뷰 기반 시나리오 테스트 실현
2. 경험하며 느낀 필요에 따른 개선
초기 검증을 완료한 후, 실제로 사용하다 보니 개선이 필요한 부분들이 명확해졌습니다.
- 테스트 실패 원인 파악의 어려움 → mochawesome 리포트 도입으로 상세한 테스트 결과 확인
- Slack 알림의 아쉬운 정보량 → S3에 리포트 업로드 후 링크 공유로 개선
- 스크린샷만으로는 부족한 디버깅 정보 → 화면 녹화 기능 추가로 테스트 과정 전체 확인 가능
- 순차 테스트로 인한 긴 실행 시간 → Matrix 전략으로 iOS/Android 병렬 테스트 구현
3. 현재 운영 상태
현재는 저희 팀에서 실제로 활용하고 있는 수준까지 발전했습니다.
운영 효과
- 💰 비용: 기존 외부 서비스 대비 확실한 비용 절감 효과
- ⚡ 효율성: PR 생성 후 자동으로 테스트가 실행되어 Slack으로 결과 확인
- 🔄 안정성: 정기 테스트를 통한 회귀 버그 조기 발견
- 👥 협업: QA와 개발팀 간 테스트 케이스 논의 증가
현재 한계점
- 디바이스 연결 불안정으로 인한 간헐적 수동 개입 필요
- 복잡한 시나리오의 불안정성으로 수동 테스트 병행 중
- 전문 디바이스 팜 대비 제약사항 존재
4. 리포트 자동화 및 시각화
- 테스트 실행 시 화면 녹화와 mochawesome 리포트를 자동으로 생성
- S3에 업로드 후 해당 링크를 Slack 메시지에 포함
- Slack에서 테스트 성공/실패뿐 아니라 결과 요약과 실행 장면까지 바로 확인 가능
- 이미지 캡쳐로는 확인이 어려워 화면 녹화로 변경 →
appium+webdriverIO를 사용하면 손쉽게 적용가능 - 개발자/QA가 Slack만으로도 테스트 상황을 직관적으로 파악 가능해짐

테스트 결과 슬랙 메시지

mochawesome의 리포트 페이지를 활용해 테스트 결과를 한눈에 확인

캡쳐 대신 화면 녹화를 이용해, 각 테스트의 과정을 구체적으로 확인
앞으로의 고도화 계획
확장성을 고려한 인프라 개선
현재 POC가 안정적으로 동작하고 있어, 더 큰 규모로 확장을 준비하고 있습니다.
인프라 확장
- 디바이스 풀 관리: iOS/Android 실기기 여러 대를 효율적으로 관리
- 로드 밸런싱: GitHub Actions 큐 시스템과 Redis를 활용한 테스트 요청 분산 및 순차 처리
- Slack 봇 UI 개선: 커맨드 입력시 버튼, 드롭다운 메뉴 추가하여 UX 향상
보안 및 안정성 강화
- AWS Lambda + API Gateway: ngrok 대신 서버리스 Webhook 엔드포인트
- Cloudflare Tunnel: 더 안정적이고 보안성 높은 터널링
모니터링 및 분석
- 메트릭 수집: 테스트 실행 시간, 성공률, 리소스 사용량 추적
- 대시보드 구축: Grafana를 활용한 테스트 성공률 및 실행 시간 모니터링
- 알림 최적화: 중요도별 알림 분류 및 노이즈 필터링
완전 자동화
- 테스트 커버리지 확장: 주요 시나리오들 대상 테스트 커버리지 80%이상 확보
- AI 기반 테스트 결과 분석: 실패 패턴 학습으로 근본 원인 자동 분석
- 자율 탐색 테스트: 개발되는 앱&웹에 맞춰서 동작하는 지능형 테스트 구성
- 셀프 힐링: 일시적 네트워크 오류 등 복구 가능한 실패 자동 재시도
정리 및 하고싶은 말
점진적 접근 방식의 실질적 효과
단기간 내 가시적 결과
- 복잡한 설정 없이 첫 테스트 자동화 경험
- Slack을 통한 실시간 테스트 결과 알림 시스템 구축
- 팀 내에서 자동화 도구에 대한 긍정적 피드백 및 추가 개선 요구사항 발생
비슷한 고민을 하는 팀이 있다면
만약 외부 테스트 서비스를 쓰고 있는데 아쉬움이 있다면:
- 저희처럼 범용 서비스와 우리 앱 특성 사이에 다른 요구사항이 있으시다면 한 번쯤 고려해볼 만합니다
- 다만 내재화에는 시간과 노력이 필요하다는 점이 있습니다
- 비용만으로 판단하기보다는 장기적 관점에서 접근하는 것을 권장합니다
완전 처음 시작하는 팀이라면:
- 작은 범위부터 시작하시기 바랍니다. 처음 부터 파이프라인을 정교하고 완벽하게 구성하려고 하면 쉽지 않습니다.
- Mac 하나 + 실기기 하나만 있어도 기본적인 자동화 경험은 충분히 가능합니다.
- 자동화된 테스트 결과 알림을 통해 지속적인 시스템 개선의 필요성을 인식하게 됩니다.
마무리
여기까지 읽어주셔서 감사드리며, 이번 포스팅도 조금이나마 많은 분들에게 도움이 되었으면 좋겠습니다.
아무래도 내용이 미흡한 부분이 있을 수 있다고 생각됩니다. 따라서, 궁금하시거나 피드백 주시고 싶으신 부분은 댓글이나 메일로 남겨주시면 감사하겠습니다 !
마지막으로 드리고싶은 말은,
처음부터 완벽을 추구하지 말고, 지금보다 조금 더 나은 것을 목표로 하다보면 최종적으로 이루고자 하시는 목표에 도달하실겁니다!
참고 자료
메타데이터
- post_id
- d0b41421dfe4
- slug
- github-action과-self-hosted-runner로-구축하는-e2e-테스트-자동화-poc부터-확장까지-우리팀의-내재화-여정-d0b41421dfe4
- url
- https://techblog.pet-friends.co.kr/github-action%EA%B3%BC-self-hosted-runner%EB%A1%9C-%EA%B5%AC%EC%B6%95%ED%95%98%EB%8A%94-e2e-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-poc%EB%B6%80%ED%84%B0-%ED%99%95%EC%9E%A5%EA%B9%8C%EC%A7%80-%EC%9A%B0%EB%A6%AC%ED%8C%80%EC%9D%98-%EB%82%B4%EC%9E%AC%ED%99%94-%EC%97%AC%EC%A0%95-d0b41421dfe4
- canonical_url
- https://techblog.pet-friends.co.kr/github-action%EA%B3%BC-self-hosted-runner%EB%A1%9C-%EA%B5%AC%EC%B6%95%ED%95%98%EB%8A%94-e2e-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-poc%EB%B6%80%ED%84%B0-%ED%99%95%EC%9E%A5%EA%B9%8C%EC%A7%80-%EC%9A%B0%EB%A6%AC%ED%8C%80%EC%9D%98-%EB%82%B4%EC%9E%AC%ED%99%94-%EC%97%AC%EC%A0%95-d0b41421dfe4
- author_url
- https://medium.com/@hu.kwon
- status
- ok
- fetched_at
- 2026-06-11 12:34:08