7.9 KiB
7.9 KiB
테스트 문제 해결 가이드
목차
소개
이 문서는 볼링 매니저 앱의 테스트 실행 중 발생할 수 있는 다양한 문제와 그 해결 방법을 설명합니다. 특히 EventBus와 MemberService 테스트의 신뢰성 문제에 초점을 맞추고 있습니다.
일반적인 테스트 실패 원인
1. 테스트 간 상태 격리 실패
증상:
- 테스트를 개별적으로 실행하면 통과하지만, 전체 테스트를 실행하면 실패
- 테스트 실행 순서에 따라 결과가 달라짐
원인:
- 테스트 간 공유 상태(싱글톤, 정적 변수 등)가 적절히 초기화되지 않음
- 테스트 종료 후 리소스가 제대로 정리되지 않음
해결 방법:
setUp과tearDown에서 모든 공유 상태 초기화- 싱글톤 인스턴스를 테스트마다 재설정
TestUtils.isInTest플래그를 활용하여 테스트 환경에서 특별한 처리 적용- 격리 모드를
strict로 설정하여 테스트 간 상태 공유 최소화
2. 타이밍 및 비동기 문제
증상:
- 간헐적인 테스트 실패
Timeout오류 발생- 비동기 작업 완료 전에 테스트가 종료됨
원인:
- 고정된 지연 시간(
Future.delayed)에 의존 - 비동기 작업 완료를 적절히 기다리지 않음
- 테스트 환경(CI vs 로컬)에 따른 실행 속도 차이
해결 방법:
- 고정 지연 대신
TestConfig에서 환경별 설정 사용 expectLater와completes매처 활용- 비동기 작업 완료를 명시적으로 기다리는 코드 추가
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 디렉토리에 저장되며, 실패 분석 및 재현 스크립트도 이 디렉토리에 생성됩니다.