본문 바로가기
개발 노트/기타

GitHub Actions Android UI 테스트 실패 로그 빠르게 분석하는 방법

by pposooj 2026. 5. 21.

GitHub Actions에서 UI 테스트를 돌리다 보면 로그가 너무 길어서 어디서부터 손대야 할지 막막할 때가 많습니다. 특히 안드로이드 프로젝트는 Gradle 빌드, androidTest 컴파일, 에뮬레이터 구동, 실제 Assertion 실패가 한 로그 안에 뒤섞여 나오다 보니 눈이 침침해지곤 하죠.

저의 경우도 매번 길고 긴 CI 로그 창을 무작정 내리다가 원인을 놓치고 한참 헤매는 경우가 많아서, 나중에 또 까먹지 않으려고 실무에서 유용한 로그 분석 순서를 정리해 둡니다.

먼저 실패 유형부터 나눈다

로그를 읽을 때 가장 먼저 할 일은 테스트가 실제로 실행되다가 깨진 건지, 아니면 테스트 단계까지 가지도 못하고 빌드나 환경 준비 단계에서 멈춘 건지 구분하는 것입니다.

운영하다 보면 같은 UI 테스트 실패처럼 보여도 원인은 전혀 다를 때가 많습니다.

실패 유형특징먼저 볼 곳
의존성 설치 실패 패키지 다운로드 오류, 캐시 문제 setup, install step
컴파일 실패 Kotlin/Java 소스 코드 에러 build, assemble step
androidTest 컴파일 실패 테스트 코드 내 import 오류, API 변경 compileDebugAndroidTest
에뮬레이터 실패 부팅 시간 초과, 권한, 시스템 이미지 문제 emulator, device step
테스트 assertion 실패 특정 테스트 케이스 검증 실패 test report, stack trace
 

화면 테스트가 실패했다고 해서 무조건 UI 코드만 볼 게 아닙니다. 컴파일 단계에서 깨졌다면 테스트 시나리오를 고치기 전에 빌드 문제부터 잡아주셔야 합니다. 화면 테스트라고 해서 항상 화면 코드가 원인인 것은 아닙니다.

로그 읽는 순서

CI 로그는 노이즈가 많기 때문에 순서를 정해두고 파고드는 게 시간 아끼는 지름길입니다. 아래 순서대로 보면 원인을 조금 더 안정적으로 좁힐 수 있습니다.

  1. 실패한 job 이름을 확인한다.
  2. 실패한 step 이름을 확인한다.
  3. 로그의 첫 번째 의미 있는 error 위치를 확인한다.
  4. 마지막 summary만 보지 말고 원인 stack trace를 확인한다.
  5. 로컬 재현 가능 여부를 판단한다.
  6. 최근 변경 파일과 실패 지점을 연결해본다.
  7. 민감 정보가 로그에 포함됐는지 확인한다.

주의하셔야 할 점 로그 맨 마지막 줄에 찍히는 Process completed with exit code 1만 보면 절대 원인을 알 수 없습니다. 이 메시지는 그냥 '실패했다'는 결과일 뿐이고, 실제 원인은 그보다 훨씬 위에 숨어 있는 경우가 많습니다. 가장 아래가 아니라 첫 번째로 의미 있는 에러를 먼저 찾는 습관이 중요합니다.

annotation과 raw log 같이 보기

GitHub Actions는 실패 위치를 UI 상에서 annotation으로 친절하게 보여주기도 합니다. 빠르게 실패한 파일이나 라인을 찾을 때는 편하지만, 이것만 보면 전체 맥락이 빠질 수 있습니다.

그래서 annotation으로 대략적인 위치를 잡았다면, 꼭 raw log를 열어서 앞뒤 흐름을 함께 보시는 편이 좋습니다. 특히 안드로이드 빌드 로그는 하나의 에러가 여러 줄로 나뉘어 표시되는 경우가 많기 때문입니다.

보는 위치장점한계
Summary 실패 job을 빠르게 확인 원인 파악에는 부족함
Annotation 실패 파일/라인 바로 확인 가능 빌드 도구별로 위치가 부정확할 수 있음
Raw log 빌드 전체 흐름 확인 가능 로그가 길고 노이즈가 많음
Artifact 테스트 리포트 및 스크린샷 확인 Actions에 업로드 설정이 선행되어야 함
 

실무 운영 관점에서는 artifact(결과물) 세팅도 필수적입니다. UI 테스트가 실패했을 때 당시의 스크린샷이나 에뮬레이터 로그, 테스트 리포트가 빌드 아티팩트로 남아 있어야 원인을 배로 빠르게 찾을 수 있습니다.

예시 로그 분류

실제 로그를 마주했을 때 어떻게 대처해야 하는지 예시로 보겠습니다.

Plaintext
 
> Task :app:compileDebugAndroidTestKotlin FAILED
error: Unresolved reference: MainScreenTestRule

FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugAndroidTestKotlin'.

이 경우는 UI 테스트가 실행되다가 실패한 것이 아니라, 테스트 코드가 컴파일조차 안 된 상태입니다. 따라서 에뮬레이터 설정이나 테스트 데이터를 볼 게 아니라 모듈 의존성이 꼬였거나, 잘못된 import, 혹은 최근에 변경된 테스트 유틸 코드가 있는지 먼저 확인해야 합니다.

반대로 아래와 같은 로그라면 에뮬레이터가 정상 구동되고 테스트가 실행된 이후의 실패로 볼 수 있습니다.

Plaintext
 
com.example.HomeScreenTest > showsTitle FAILED
java.lang.AssertionError: Expected text was not found

이 경우에는 화면 렌더링 속도 문제, UI 셀렉터(Selector) 오류, 초기 데이터 세팅, 혹은 비동기 로딩 대기 조건(Idling Resource 등)을 점검하셔야 합니다. 로그에 테스트 케이스 이름이 나와 있다면 해당 화면 코드부터 좁혀가면 됩니다.

로컬 재현 기준

CI 서버에서 수정하고 커밋 날리며 확인하면 시간이 너무 오래 걸립니다. 로컬 환경에서 먼저 재현되는지 단계를 나누어 명령어를 실행해보는 것이 좋습니다. 안드로이드 프로젝트라면 실패 단계에 맞춰 아래 명령을 나눠 실행해봅니다.

  • 컴파일 단계 실패 시: ./gradlew assembleDebug 또는 ./gradlew compileDebugAndroidTestKotlin
  • 테스트 실행 단계 실패 시: ./gradlew connectedDebugAndroidTest

컴파일 실패라면 굳이 무거운 에뮬레이터까지 띄우는 명령을 돌릴 필요 없이 컴파일 명령만 확인하면 됩니다. (만약 React Native나 웹 테스트 환경이라면 프로젝트 스크립트에 맞춰 test, lint, e2e 같은 명령어로 쪼개서 확인하시면 됩니다.)

민감 정보 제거 기준

가끔 에러 원인을 찾으려고 로그를 블로그나 외부 커뮤니티에 그대로 붙여넣는 경우가 있습니다. 이때 생각보다 많은 중요 정보가 노출되곤 하니 꼭 주의하셔야 합니다. 로그를 공유할 때는 핵심 원인만 남기고 민감 정보는 [REDACTED] 처럼 마스킹하는 습관을 들입시다.

  • API URL: 공개 가능한 예시 URL로 바꾼다.
  • 인증 토큰: 토큰이나 API Key가 일부라도 보이면 마스킹한다.
  • Firebase 설정: 실제 프로젝트명이 드러나지 않게 경로를 수정한다.
  • Keystore: 빌드에 사용된 keystore 경로와 자격 증명 정보는 노출하지 않는다.
  • 환경 정보: 내부 브랜치명이나 스테이징/운영 배포 환경명이 노출되는지 확인한다.
  • 테스트 계정: 로그에 찍힌 이메일 등은 test@example.com 같은 예시 계정으로 바꾼다.
  • 서버 응답: Response Body 전문을 올릴 때 개인정보나 비공개 데이터가 없는지 확인한다.

테스트 실패 분석 체크리스트

장애 대응이나 코드 리뷰 때 일관된 기준으로 로그를 보기 위해 아래 체크리스트를 만들어 두고 활용하시면 시간을 많이 줄일 수 있습니다.

  • [ ] 실패한 job과 step을 명확히 구분했는가?
  • [ ] 맨 아래 종료 코드 말고, '첫 번째 의미 있는 error'를 찾았는가?
  • [ ] 테스트 실행 실패인지, 테스트 컴파일 실패인지 구분했는가?
  • [ ] 로컬에서 재현해 볼 명령어를 정확히 파악했는가?
  • [ ] 로그에서 토큰, 서버 URL, 계정 등 민감 정보를 마스킹했는가?
  • [ ] Artifact에 실패 스크린샷이나 테스트 리포트가 남도록 설정했는가?

자주 하는 실수

  1. 로그 맨 아래만 보고 원인을 판단하는 경우: 맨 아래에는 종료 코드(exit code 1)만 있고, 진짜 원인은 훨씬 위에 있는 경우가 대부분입니다.
  2. UI 테스트 자체 실패로 오해하는 경우: 실제로는 테스트 코드 컴파일 실패인데, 엄한 화면 코드나 대기 시간만 계속 고치고 있으면 시간이 오래 걸립니다.
  3. annotation만 보고 raw log를 확인하지 않는 경우: annotation은 편리하지만 전체 빌드 흐름이나 앞뒤 맥락을 놓치기 쉽습니다.

결론

GitHub Actions 로그가 길고 복잡해 보여도, 실패 유형만 차근차근 나누면 길을 잃지 않습니다. 요약하자면 Job/Step 확인 → 첫 번째 에러 찾기 → 로컬 재현 → 민감 정보 체크 순서만 몸에 익혀두셔도 삽질 시간이 절반으로 줄어듭니다.

마지막 Summary 결과만 보지 말고, Raw Log에서 스택 트레이스 흐름을 짚어내는 습관을 들여보세요. 오늘 정리한 내용이 도움이 되셨으면 좋겠습니다.