import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:yaml/yaml.dart'; import 'package:path/path.dart' as path; /// CI/CD 환경과 로컬 환경에서 테스트 실행 시 설정을 관리하는 클래스 class TestConfig { static TestConfig? _instance; // 기본 설정값 int asyncTimeout = 800; int testDelay = 100; int retryCount = 1; bool parallel = true; int memoryLimit = 0; // 0은 제한 없음 int logLevel = 2; String isolationMode = 'normal'; int timerCompletionWait = 500; // 테스트 종료 전 타이머 완료 대기 시간 bool isCI = false; /// 싱글톤 인스턴스 반환 static TestConfig get instance { _instance ??= TestConfig._internal(); return _instance!; } TestConfig._internal() { _loadConfig(); } /// 설정 파일 로드 void _loadConfig() { try { // CI 환경 감지 isCI = Platform.environment.containsKey('CI') || Platform.environment.containsKey('GITHUB_ACTIONS') || Platform.environment.containsKey('GITLAB_CI'); if (kDebugMode) { print('TestConfig: CI 환경 감지 - $isCI'); } // 설정 파일 경로 final configPath = isCI ? '.github/workflows/test_config.yaml' : 'test/test_config.yaml'; // 프로젝트 루트 디렉토리 찾기 String projectRoot = Directory.current.path; // pubspec.yaml이 있는 디렉토리를 찾을 때까지 상위 디렉토리로 이동 while (!File(path.join(projectRoot, 'pubspec.yaml')).existsSync()) { final parent = Directory(projectRoot).parent; if (parent.path == projectRoot) { // 루트에 도달했는데도 pubspec.yaml을 찾지 못함 break; } projectRoot = parent.path; } final configFile = File(path.join(projectRoot, configPath)); if (configFile.existsSync()) { final yamlString = configFile.readAsStringSync(); final yamlMap = loadYaml(yamlString) as Map; if (yamlMap.containsKey('test_settings')) { final settings = yamlMap['test_settings'] as Map; asyncTimeout = settings['async_timeout'] ?? asyncTimeout; testDelay = settings['test_delay'] ?? testDelay; retryCount = settings['retry_count'] ?? retryCount; parallel = settings['parallel'] ?? parallel; memoryLimit = settings['memory_limit'] ?? memoryLimit; logLevel = settings['log_level'] ?? logLevel; isolationMode = settings['isolation_mode'] ?? isolationMode; timerCompletionWait = settings['timer_completion_wait'] ?? timerCompletionWait; if (kDebugMode) { print('TestConfig: 설정 파일 로드 성공 - $configPath'); print('TestConfig: asyncTimeout=$asyncTimeout, testDelay=$testDelay, retryCount=$retryCount'); } } } else { if (kDebugMode) { print('TestConfig: 설정 파일 없음 - $configPath, 기본값 사용'); } } } catch (e) { if (kDebugMode) { print('TestConfig: 설정 로드 중 오류 - $e'); } } } /// 테스트 환경에 맞는 비동기 타임아웃 값 반환 Duration get asyncTimeoutDuration => Duration(milliseconds: asyncTimeout); /// 테스트 환경에 맞는 테스트 간 지연 시간 반환 Duration get testDelayDuration => Duration(milliseconds: testDelay); /// 테스트 종료 전 타이머 완료 대기 시간 반환 Duration get timerCompletionWaitDuration => Duration(milliseconds: timerCompletionWait); /// 테스트 환경에 맞는 로그 레벨 반환 (디버깅 상세도) bool get isVerboseLogging => logLevel >= 4; /// 테스트 격리 모드가 strict인지 확인 bool get isStrictIsolation => isolationMode == 'strict'; }