Files
bowlingManager/mobile/docs/TEST_TROUBLESHOOTING.md
T
2025-08-12 03:28:08 +09:00

7.9 KiB

테스트 문제 해결 가이드

목차

  1. 소개
  2. 일반적인 테스트 실패 원인
  3. EventBus 관련 문제
  4. 비동기 테스트 문제
  5. 메모리 및 리소스 관리 문제
  6. CI 환경 특화 문제
  7. 문제 해결 도구
  8. 테스트 실행 가이드

소개

이 문서는 볼링 매니저 앱의 테스트 실행 중 발생할 수 있는 다양한 문제와 그 해결 방법을 설명합니다. 특히 EventBus와 MemberService 테스트의 신뢰성 문제에 초점을 맞추고 있습니다.

일반적인 테스트 실패 원인

1. 테스트 간 상태 격리 실패

증상:

  • 테스트를 개별적으로 실행하면 통과하지만, 전체 테스트를 실행하면 실패
  • 테스트 실행 순서에 따라 결과가 달라짐

원인:

  • 테스트 간 공유 상태(싱글톤, 정적 변수 등)가 적절히 초기화되지 않음
  • 테스트 종료 후 리소스가 제대로 정리되지 않음

해결 방법:

  • setUptearDown에서 모든 공유 상태 초기화
  • 싱글톤 인스턴스를 테스트마다 재설정
  • TestUtils.isInTest 플래그를 활용하여 테스트 환경에서 특별한 처리 적용
  • 격리 모드를 strict로 설정하여 테스트 간 상태 공유 최소화

2. 타이밍 및 비동기 문제

증상:

  • 간헐적인 테스트 실패
  • Timeout 오류 발생
  • 비동기 작업 완료 전에 테스트가 종료됨

원인:

  • 고정된 지연 시간(Future.delayed)에 의존
  • 비동기 작업 완료를 적절히 기다리지 않음
  • 테스트 환경(CI vs 로컬)에 따른 실행 속도 차이

해결 방법:

  • 고정 지연 대신 TestConfig에서 환경별 설정 사용
  • expectLatercompletes 매처 활용
  • 비동기 작업 완료를 명시적으로 기다리는 코드 추가

EventBus 관련 문제

1. 구독 해제 문제

증상:

  • EventBus: 구독 취소됨 로그가 누락됨
  • 활성 구독 수(_activeSubscriptionCount)가 감소하지 않음
  • 테스트 간 이벤트 간섭 발생

원인:

  • dispose() 메서드에서 구독 취소가 제대로 이루어지지 않음
  • 구독 취소 전에 테스트가 종료됨
  • 구독 카운터 관리 버그

해결 방법:

  • dispose() 메서드에서 모든 구독을 명시적으로 취소
  • tearDown에서 EventBus.resetAllTestInstances() 호출
  • 테스트 ID를 사용하여 테스트별 EventBus 인스턴스 격리

2. 이벤트 전달 문제

증상:

  • 이벤트가 발생했지만 구독자에게 전달되지 않음
  • 테스트에서 이벤트 처리 검증 실패

원인:

  • 이벤트 발생과 처리 사이의 비동기 타이밍 문제
  • 잘못된 테스트 ID로 인한 이벤트 격리
  • 이벤트 구독 전에 이벤트가 발생함

해결 방법:

  • 이벤트 발생 후 적절한 지연 추가 (환경 설정 기반)
  • 테스트 ID 설정 확인
  • 이벤트 발생 전에 구독이 완료되었는지 확인

비동기 테스트 문제

1. 타임아웃 문제

증상:

  • Test timed out after X milliseconds 오류
  • CI 환경에서 더 자주 발생

원인:

  • 테스트 타임아웃 값이 너무 짧음
  • 비동기 작업이 예상보다 오래 걸림
  • 리소스 경합으로 인한 지연

해결 방법:

  • TestConfig를 통해 환경별 타임아웃 값 조정
  • 비동기 작업 완료를 명시적으로 기다림
  • CI 환경에서 더 긴 타임아웃 설정

2. 비동기 작업 완료 대기 문제

증상:

  • 비동기 작업 결과를 검증하기 전에 테스트가 종료됨
  • 간헐적인 테스트 실패

원인:

  • await가 누락됨
  • 잘못된 비동기 패턴 사용
  • 이벤트 루프 블로킹

해결 방법:

  • 모든 비동기 작업에 await 사용
  • expectLater와 함께 completes 또는 completion 매처 사용
  • pumpAndSettle을 사용하여 모든 마이크로태스크가 완료될 때까지 대기

메모리 및 리소스 관리 문제

1. 리소스 누수

증상:

  • 메모리 사용량 증가
  • 테스트 실행이 느려짐
  • 장시간 테스트 실행 시 실패 증가

원인:

  • dispose() 메서드에서 리소스 정리 누락
  • 구독, 스트림, 컨트롤러 등이 제대로 닫히지 않음
  • 테스트 간 공유 리소스가 정리되지 않음

해결 방법:

  • 모든 서비스 클래스에 철저한 dispose() 구현
  • tearDown에서 모든 리소스 정리
  • 메모리 누수 감지 도구 활용

2. 구독 관리 문제

증상:

  • EventBus 활성 구독 수가 계속 증가
  • 이벤트가 예상보다 많은 구독자에게 전달됨

원인:

  • 구독 취소가 제대로 이루어지지 않음
  • 구독 카운터 관리 버그
  • 테스트 간 구독 객체 공유

해결 방법:

  • 모든 구독을 변수에 저장하고 명시적으로 취소
  • StreamSubscription 객체 관리 개선
  • 테스트 ID 기반 구독 격리

CI 환경 특화 문제

1. 환경 차이로 인한 문제

증상:

  • 로컬에서는 통과하지만 CI에서는 실패하는 테스트
  • CI에서 더 느린 테스트 실행 속도
  • 리소스 제약으로 인한 타임아웃

원인:

  • CI 환경의 제한된 리소스 (CPU, 메모리)
  • 환경별 설정 차이
  • 병렬 실행으로 인한 리소스 경합

해결 방법:

  • 환경 감지 및 설정 자동 조정 (TestConfig 활용)
  • CI 환경에서 더 긴 타임아웃 및 지연 설정
  • 필요시 CI에서 순차 실행 적용

2. 로깅 및 디버깅 문제

증상:

  • CI에서 테스트 실패 원인 파악이 어려움
  • 로그 정보 부족

원인:

  • CI 환경에서 제한된 로그 출력
  • 디버깅 정보 부족

해결 방법:

  • CI 환경에서 상세 로깅 활성화
  • TestDiagnostics 유틸리티를 통한 자동 진단 정보 수집
  • 실패 시 시스템 정보 수집 및 저장

문제 해결 도구

1. 테스트 진단 유틸리티

TestDiagnostics 클래스는 테스트 실패 시 자동으로 진단 정보를 수집하고 분석합니다:

// 테스트 실패 기록
TestDiagnostics.instance.recordFailure(
  '테스트 이름',
  '오류 메시지',
  stackTrace: stackTrace
);

// 테스트 종료 시 요약 생성
await TestDiagnostics.instance.generateSummary();

2. 테스트 재현 스크립트

테스트 실패를 재현하고 진단하기 위한 스크립트:

# 특정 테스트 재현
./scripts/reproduce_test.sh "MemberService 테스트" --verbose

# 환경별 테스트 실행
./scripts/run_tests.sh ci --pattern="EventBus" --timeout=3000

3. 테스트 설정 관리

환경별 테스트 설정을 관리하기 위한 TestConfig 클래스:

// 환경별 설정 사용
final timeout = TestConfig.instance.asyncTimeout;
final delay = TestConfig.instance.testDelayDuration;

// 비동기 작업 대기
await Future.delayed(delay);

테스트 실행 가이드

로컬 환경에서 테스트 실행

# 전체 테스트 실행
./scripts/run_tests.sh local

# 특정 테스트만 실행
./scripts/run_tests.sh local --pattern="MemberService"

# 상세 로그와 함께 실행
./scripts/run_tests.sh local --verbose

CI 환경에서 테스트 실행

# CI 환경 설정으로 테스트 실행
./scripts/run_tests.sh ci

# 순차 실행 (병렬 실행 비활성화)
./scripts/run_tests.sh ci --sequential

# 타임아웃 증가
./scripts/run_tests.sh ci --timeout=5000

테스트 실패 분석

# 실패한 테스트 재현
./scripts/reproduce_test.sh "실패한 테스트 이름"

# 진단 정보 수집
./scripts/reproduce_test.sh "실패한 테스트 이름" --verbose

테스트 진단 로그는 test_diagnostics 디렉토리에 저장되며, 실패 분석 및 재현 스크립트도 이 디렉토리에 생성됩니다.