TDD 작성
This commit is contained in:
Executable
+389
@@ -0,0 +1,389 @@
|
||||
#!/bin/bash
|
||||
# 환경별 테스트 실행 스크립트
|
||||
# 사용법: ./scripts/run_tests.sh [환경] [옵션]
|
||||
|
||||
# 색상 정의
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 기본 설정
|
||||
ENVIRONMENT="local" # local, ci 또는 stress
|
||||
TEST_PATTERN=""
|
||||
COLLECT_DIAGNOSTICS=1
|
||||
VERBOSE=0
|
||||
RETRY_COUNT=""
|
||||
TIMEOUT_MS=""
|
||||
ISOLATION_MODE=""
|
||||
PARALLEL=""
|
||||
REPEAT_COUNT=1
|
||||
|
||||
# 스크립트 경로 설정
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
DIAGNOSTICS_DIR="$PROJECT_ROOT/test_diagnostics"
|
||||
|
||||
# 사용법 출력
|
||||
usage() {
|
||||
echo -e "${BLUE}환경별 테스트 실행 스크립트${NC}"
|
||||
echo "사용법: $0 [환경] [옵션]"
|
||||
echo ""
|
||||
echo "환경:"
|
||||
echo " local 로컬 환경 설정 사용 (기본값)"
|
||||
echo " ci CI 환경 설정 사용"
|
||||
echo " stress 스트레스 테스트 환경 설정 사용"
|
||||
echo ""
|
||||
echo "옵션:"
|
||||
echo " -p, --pattern=PATTERN 테스트 패턴 지정 (예: \"MemberService\")"
|
||||
echo " -v, --verbose 상세 로그 출력"
|
||||
echo " -n, --no-diagnostics 진단 정보 수집 비활성화"
|
||||
echo " -r, --retry=N 재시도 횟수 설정 (환경 설정 재정의)"
|
||||
echo " -t, --timeout=MS 타임아웃 설정 (밀리초, 환경 설정 재정의)"
|
||||
echo " -i, --isolation=MODE 격리 모드 설정 (strict, normal, relaxed)"
|
||||
echo " -s, --sequential 순차 실행 (병렬 실행 비활성화)"
|
||||
echo " -c, --repeat=N 테스트 반복 실행 횟수"
|
||||
echo " -h, --help 도움말 표시"
|
||||
echo ""
|
||||
echo "예시:"
|
||||
echo " $0 local --pattern=\"MemberService\" --verbose"
|
||||
echo " $0 ci --timeout=3000 --retry=5"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 매개변수 파싱
|
||||
parse_params() {
|
||||
# 첫 번째 매개변수가 환경인지 확인
|
||||
if [ $# -gt 0 ] && [[ "$1" != -* ]]; then
|
||||
case "$1" in
|
||||
local|ci)
|
||||
ENVIRONMENT="$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}오류: 알 수 없는 환경: $1${NC}"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# 나머지 매개변수 처리
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-p=*|--pattern=*)
|
||||
TEST_PATTERN="${1#*=}"
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSE=1
|
||||
;;
|
||||
-n|--no-diagnostics)
|
||||
COLLECT_DIAGNOSTICS=0
|
||||
;;
|
||||
-r=*|--retry=*)
|
||||
RETRY_COUNT="${1#*=}"
|
||||
;;
|
||||
-t=*|--timeout=*)
|
||||
TIMEOUT_MS="${1#*=}"
|
||||
;;
|
||||
-i=*|--isolation=*)
|
||||
ISOLATION_MODE="${1#*=}"
|
||||
;;
|
||||
-s|--sequential)
|
||||
PARALLEL="--no-concurrency"
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}오류: 알 수 없는 옵션: $1${NC}"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
# 환경 설정 로드
|
||||
load_environment_settings() {
|
||||
echo -e "${BLUE}환경 설정 로드: $ENVIRONMENT${NC}"
|
||||
|
||||
local CONFIG_FILE="$PROJECT_ROOT/test/test_config.yaml"
|
||||
|
||||
# 설정 파일 존재 확인
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
echo -e "${RED}오류: 설정 파일을 찾을 수 없음: $CONFIG_FILE${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 환경 설정 출력
|
||||
case "$ENVIRONMENT" in
|
||||
"ci")
|
||||
echo -e "${YELLOW}CI 환경 설정 사용${NC}"
|
||||
export FLUTTER_TEST_IS_CI=true
|
||||
export FLUTTER_TEST_IS_STRESS=false
|
||||
;;
|
||||
"stress")
|
||||
echo -e "${YELLOW}스트레스 테스트 환경 설정 사용${NC}"
|
||||
export FLUTTER_TEST_IS_CI=false
|
||||
export FLUTTER_TEST_IS_STRESS=true
|
||||
;;
|
||||
*)
|
||||
echo -e "${YELLOW}로컬 환경 설정 사용${NC}"
|
||||
export FLUTTER_TEST_IS_CI=false
|
||||
export FLUTTER_TEST_IS_STRESS=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# YAML 파일에서 설정 추출
|
||||
if [ -z "$RETRY_COUNT" ]; then
|
||||
RETRY_COUNT=$(grep "$ENVIRONMENT:" -A 10 "$CONFIG_FILE" | grep "retry_count:" | head -n 1 | awk '{print $2}')
|
||||
fi
|
||||
|
||||
if [ -z "$TIMEOUT_MS" ]; then
|
||||
TIMEOUT_MS=$(grep "$ENVIRONMENT:" -A 10 "$CONFIG_FILE" | grep "async_timeout:" | head -n 1 | awk '{print $2}')
|
||||
fi
|
||||
|
||||
if [ -z "$ISOLATION_MODE" ]; then
|
||||
ISOLATION_MODE=$(grep "$ENVIRONMENT:" -A 10 "$CONFIG_FILE" | grep "isolation_mode:" | head -n 1 | awk '{print $2}')
|
||||
fi
|
||||
|
||||
# 진단 로깅 설정
|
||||
if [ "$COLLECT_DIAGNOSTICS" -eq 1 ]; then
|
||||
local DIAGNOSTICS_ENABLED=$(grep "$ENVIRONMENT:" -A 10 "$CONFIG_FILE" | grep "diagnostics_enabled:" | head -n 1 | awk '{print $2}')
|
||||
if [ "$DIAGNOSTICS_ENABLED" = "false" ]; then
|
||||
COLLECT_DIAGNOSTICS=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$PARALLEL" ]; then
|
||||
local PARALLEL_SETTING=$(grep "$ENVIRONMENT:" -A 10 "$CONFIG_FILE" | grep "parallel:" | head -n 1 | awk '{print $2}')
|
||||
if [ "$PARALLEL_SETTING" = "false" ]; then
|
||||
PARALLEL="--no-concurrency"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 환경 변수 설정
|
||||
export FLUTTER_TEST_TIMEOUT_OVERRIDE="$TIMEOUT_MS"
|
||||
export FLUTTER_TEST_RETRY_COUNT="$RETRY_COUNT"
|
||||
export FLUTTER_TEST_ISOLATION_MODE="$ISOLATION_MODE"
|
||||
export FLUTTER_TEST_DIAGNOSTICS="$COLLECT_DIAGNOSTICS"
|
||||
export FLUTTER_TEST_ENVIRONMENT="$ENVIRONMENT"
|
||||
|
||||
echo -e "${GREEN}설정 로드 완료: 환경=$ENVIRONMENT, 재시도=$RETRY_COUNT, 타임아웃=$TIMEOUT_MS ms, 격리=$ISOLATION_MODE${NC}"
|
||||
if [ "$REPEAT_COUNT" -gt 1 ]; then
|
||||
echo -e "${GREEN}테스트 반복 실행: $REPEAT_COUNT회${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 진단 디렉토리 설정
|
||||
setup_diagnostics() {
|
||||
if [ $COLLECT_DIAGNOSTICS -eq 1 ]; then
|
||||
mkdir -p "$DIAGNOSTICS_DIR"
|
||||
echo -e "${BLUE}진단 정보 수집 활성화: $DIAGNOSTICS_DIR${NC}"
|
||||
|
||||
# 테스트 실행 시간 기록
|
||||
export FLUTTER_TEST_RUN_ID="test_run_$(date +%Y%m%d_%H%M%S)"
|
||||
export FLUTTER_TEST_LOG_DIR="$DIAGNOSTICS_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# 테스트 실행
|
||||
run_tests() {
|
||||
echo -e "${BLUE}테스트 실행 시작${NC}"
|
||||
|
||||
# 테스트 명령 구성
|
||||
TEST_CMD="flutter test"
|
||||
|
||||
if [ -n "$TEST_PATTERN" ]; then
|
||||
TEST_CMD="$TEST_CMD --name=\"$TEST_PATTERN\""
|
||||
fi
|
||||
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
TEST_CMD="$TEST_CMD --verbose"
|
||||
fi
|
||||
|
||||
if [ -n "$PARALLEL" ]; then
|
||||
TEST_CMD="$TEST_CMD $PARALLEL"
|
||||
fi
|
||||
|
||||
# 테스트 실행 및 결과 저장
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# 반복 실행 설정
|
||||
OVERALL_RESULT=0
|
||||
FAILED_RUNS=0
|
||||
SUCCESSFUL_RUNS=0
|
||||
|
||||
echo -e "${BLUE}테스트 반복 실행: $REPEAT_COUNT회${NC}"
|
||||
|
||||
for ((i=1; i<=$REPEAT_COUNT; i++)); do
|
||||
if [ $REPEAT_COUNT -gt 1 ]; then
|
||||
echo -e "\n${YELLOW}===== 테스트 실행 $i/$REPEAT_COUNT =====${NC}\n"
|
||||
fi
|
||||
|
||||
if [ $COLLECT_DIAGNOSTICS -eq 1 ]; then
|
||||
LOG_FILE="$DIAGNOSTICS_DIR/test_run_$(date +%Y%m%d_%H%M%S)_${i}_of_${REPEAT_COUNT}.log"
|
||||
echo -e "${YELLOW}테스트 로그 저장: $LOG_FILE${NC}"
|
||||
|
||||
# 테스트 실행 시작 시간 기록
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
# 테스트 실행 및 로그 저장
|
||||
echo -e "${YELLOW}실행 명령: $TEST_CMD${NC}"
|
||||
eval "$TEST_CMD" 2>&1 | tee "$LOG_FILE"
|
||||
RUN_RESULT=${PIPESTATUS[0]}
|
||||
|
||||
# 테스트 실행 종료 시간 기록
|
||||
END_TIME=$(date +%s)
|
||||
DURATION=$((END_TIME - START_TIME))
|
||||
else
|
||||
# 진단 없이 테스트 실행
|
||||
START_TIME=$(date +%s)
|
||||
echo -e "${YELLOW}실행 명령: $TEST_CMD${NC}"
|
||||
eval "$TEST_CMD"
|
||||
RUN_RESULT=$?
|
||||
END_TIME=$(date +%s)
|
||||
DURATION=$((END_TIME - START_TIME))
|
||||
fi
|
||||
|
||||
# 테스트 결과 처리
|
||||
if [ $RUN_RESULT -eq 0 ]; then
|
||||
echo -e "${GREEN}테스트 성공! (실행 $i/$REPEAT_COUNT, 소요 시간: ${DURATION}초)${NC}"
|
||||
SUCCESSFUL_RUNS=$((SUCCESSFUL_RUNS + 1))
|
||||
else
|
||||
echo -e "${RED}테스트 실패! (실행 $i/$REPEAT_COUNT, 종료 코드: $RUN_RESULT, 소요 시간: ${DURATION}초)${NC}"
|
||||
FAILED_RUNS=$((FAILED_RUNS + 1))
|
||||
OVERALL_RESULT=1
|
||||
|
||||
if [ $COLLECT_DIAGNOSTICS -eq 1 ]; then
|
||||
echo -e "${YELLOW}진단 정보 분석 중...${NC}"
|
||||
analyze_results "$LOG_FILE"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# 총결과 출력
|
||||
if [ $REPEAT_COUNT -gt 1 ]; then
|
||||
echo -e "\n${BLUE}===== 테스트 반복 실행 총결과 =====${NC}"
|
||||
echo -e "${BLUE}총 실행 횟수: $REPEAT_COUNT${NC}"
|
||||
echo -e "${GREEN}성공한 실행: $SUCCESSFUL_RUNS${NC}"
|
||||
echo -e "${RED}실패한 실행: $FAILED_RUNS${NC}"
|
||||
|
||||
if [ $OVERALL_RESULT -eq 0 ]; then
|
||||
echo -e "${GREEN}총결과: 모든 테스트 성공!${NC}"
|
||||
else
|
||||
echo -e "${RED}총결과: 실패한 테스트 발견!${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
return $OVERALL_RESULT
|
||||
}
|
||||
|
||||
# 결과 분석
|
||||
analyze_results() {
|
||||
local LOG_FILE="$1"
|
||||
local ANALYSIS_FILE="$DIAGNOSTICS_DIR/analysis_$(date +%Y%m%d_%H%M%S).txt"
|
||||
|
||||
echo "=== 테스트 실행 분석 ===" > "$ANALYSIS_FILE"
|
||||
echo "분석 시간: $(date)" >> "$ANALYSIS_FILE"
|
||||
echo "환경: $ENVIRONMENT" >> "$ANALYSIS_FILE"
|
||||
echo "테스트 패턴: ${TEST_PATTERN:-'전체 테스트'}" >> "$ANALYSIS_FILE"
|
||||
echo "설정:" >> "$ANALYSIS_FILE"
|
||||
echo " - 재시도 횟수: $RETRY_COUNT" >> "$ANALYSIS_FILE"
|
||||
echo " - 타임아웃: $TIMEOUT_MS ms" >> "$ANALYSIS_FILE"
|
||||
echo " - 격리 모드: $ISOLATION_MODE" >> "$ANALYSIS_FILE"
|
||||
echo "" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 실패한 테스트 목록 추출
|
||||
echo "== 실패한 테스트 ==" >> "$ANALYSIS_FILE"
|
||||
grep -i "fail\|failed\|failure" "$LOG_FILE" | grep -v "Expected" | sort | uniq >> "$ANALYSIS_FILE" 2>/dev/null || echo "없음" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 타임아웃 관련 오류 검색
|
||||
echo "" >> "$ANALYSIS_FILE"
|
||||
echo "== 타임아웃 관련 오류 ==" >> "$ANALYSIS_FILE"
|
||||
grep -i "timeout\|timed out" "$LOG_FILE" >> "$ANALYSIS_FILE" 2>/dev/null || echo "없음" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 비동기 관련 오류 검색
|
||||
echo "" >> "$ANALYSIS_FILE"
|
||||
echo "== 비동기 관련 오류 ==" >> "$ANALYSIS_FILE"
|
||||
grep -i "async\|await\|future\|stream\|pending timer" "$LOG_FILE" | grep -i "error\|exception\|fail" >> "$ANALYSIS_FILE" 2>/dev/null || echo "없음" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 이벤트 버스 관련 오류 검색
|
||||
echo "" >> "$ANALYSIS_FILE"
|
||||
echo "== 이벤트 버스 관련 오류 ==" >> "$ANALYSIS_FILE"
|
||||
grep -i "eventbus\|event bus\|subscription" "$LOG_FILE" | grep -i "error\|exception\|fail" >> "$ANALYSIS_FILE" 2>/dev/null || echo "없음" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 메모리 관련 오류 검색
|
||||
echo "" >> "$ANALYSIS_FILE"
|
||||
echo "== 메모리 관련 오류 ==" >> "$ANALYSIS_FILE"
|
||||
grep -i "memory\|leak\|dispose\|resource" "$LOG_FILE" | grep -i "error\|exception\|fail" >> "$ANALYSIS_FILE" 2>/dev/null || echo "없음" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 추천 조치 생성
|
||||
echo "" >> "$ANALYSIS_FILE"
|
||||
echo "== 추천 조치 ==" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 타임아웃 관련 추천
|
||||
if grep -qi "timeout\|timed out" "$LOG_FILE"; then
|
||||
echo "- 타임아웃 값을 증가시켜 보세요 (현재: $TIMEOUT_MS ms, 추천: $((TIMEOUT_MS * 2)) ms)" >> "$ANALYSIS_FILE"
|
||||
echo "- 비동기 작업 완료를 기다리는 코드를 검토하세요" >> "$ANALYSIS_FILE"
|
||||
echo "- 테스트에서 사용하는 지연 시간(delay)을 늘려보세요" >> "$ANALYSIS_FILE"
|
||||
fi
|
||||
|
||||
# 이벤트 버스 관련 추천
|
||||
if grep -qi "eventbus\|event bus\|subscription" "$LOG_FILE" && grep -qi "error\|exception\|fail" "$LOG_FILE"; then
|
||||
echo "- EventBus 구독 해제 코드를 확인하세요" >> "$ANALYSIS_FILE"
|
||||
echo "- dispose() 메서드에서 모든 리소스가 정리되는지 확인하세요" >> "$ANALYSIS_FILE"
|
||||
echo "- 테스트 간 격리 모드를 'strict'로 설정해 보세요" >> "$ANALYSIS_FILE"
|
||||
fi
|
||||
|
||||
# 메모리 관련 추천
|
||||
if grep -qi "memory\|leak\|dispose\|resource" "$LOG_FILE" && grep -qi "error\|exception\|fail" "$LOG_FILE"; then
|
||||
echo "- 메모리 누수 가능성이 있습니다. dispose() 메서드를 확인하세요" >> "$ANALYSIS_FILE"
|
||||
echo "- 테스트 종료 후 모든 리소스가 정리되는지 확인하세요" >> "$ANALYSIS_FILE"
|
||||
echo "- 테스트 간 상태 공유를 최소화하세요" >> "$ANALYSIS_FILE"
|
||||
fi
|
||||
|
||||
# 실패한 테스트가 있으면 재현 스크립트 생성
|
||||
if grep -qi "fail\|failed\|failure" "$LOG_FILE" | grep -v "Expected"; then
|
||||
echo "" >> "$ANALYSIS_FILE"
|
||||
echo "== 실패 테스트 재현 방법 ==" >> "$ANALYSIS_FILE"
|
||||
echo "다음 명령으로 실패한 테스트를 격리하여 재실행할 수 있습니다:" >> "$ANALYSIS_FILE"
|
||||
|
||||
# 실패한 테스트 이름 추출 시도
|
||||
FAILED_TEST=$(grep -i "fail\|failed\|failure" "$LOG_FILE" | grep -v "Expected" | head -n 1 | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
|
||||
if [ -n "$FAILED_TEST" ]; then
|
||||
echo "./scripts/reproduce_test.sh \"$FAILED_TEST\" --verbose --retry=$RETRY_COUNT --timeout=$TIMEOUT_MS --isolation=$ISOLATION_MODE" >> "$ANALYSIS_FILE"
|
||||
else
|
||||
echo "./scripts/reproduce_test.sh \"[테스트이름]\" --verbose --retry=$RETRY_COUNT --timeout=$TIMEOUT_MS --isolation=$ISOLATION_MODE" >> "$ANALYSIS_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# 분석 결과 요약 출력
|
||||
echo -e "${YELLOW}=== 분석 요약 ===${NC}"
|
||||
cat "$ANALYSIS_FILE" | grep -v "없음" | head -n 20
|
||||
|
||||
# 실패한 테스트가 있으면 재현 명령 제안
|
||||
if grep -qi "fail\|failed\|failure" "$LOG_FILE" | grep -v "Expected"; then
|
||||
FAILED_TEST=$(grep -i "fail\|failed\|failure" "$LOG_FILE" | grep -v "Expected" | head -n 1 | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
|
||||
if [ -n "$FAILED_TEST" ]; then
|
||||
echo -e "${YELLOW}실패한 테스트 재현 명령:${NC}"
|
||||
echo -e "${BLUE}./scripts/reproduce_test.sh \"$FAILED_TEST\" --verbose${NC}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 메인 실행 흐름
|
||||
main() {
|
||||
parse_params "$@"
|
||||
load_environment_settings
|
||||
setup_diagnostics
|
||||
run_tests
|
||||
exit $?
|
||||
}
|
||||
|
||||
# 스크립트 실행
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user