# BaseScreenTest 사용 가이드

## 개요
BaseScreenTest는 모든 화면 테스트의 기본 클래스로, 다음과 같은 기능을 제공합니다:

- ✅ 공통 CRUD 테스트 패턴의 표준화된 구현
- ✅ 에러 자동 진단 및 수정 플로우
- ✅ 테스트 데이터 자동 생성/정리
- ✅ 병렬 테스트 실행을 위한 격리 보장
- ✅ 화면별 특수 기능 테스트를 위한 확장 포인트

## 주요 개선사항

### 1. 자동 재시도 메커니즘
```dart
// 모든 CRUD 작업에 자동 재시도 로직이 적용됩니다
static const int maxRetryAttempts = 3;
static const Duration retryDelay = Duration(seconds: 1);
```

### 2. 에러 자동 수정 플로우
```dart
// 에러 발생 시 자동으로 진단하고 수정을 시도합니다
Future<bool> _handleCrudError(dynamic error, String operation, TestData data)
```

### 3. 병렬 실행 지원
```dart
// 고유한 세션 ID와 리소스 잠금으로 병렬 테스트가 가능합니다
late final String testSessionId;
static final Map<String, Completer<void>> _resourceLocks = {};
```

### 4. 향상된 로깅
```dart
// 모든 작업이 상세히 로깅되며, 리포트에도 자동으로 기록됩니다
void _log(String message)
```

## 구현 방법

### 1. 기본 구조
```dart
class YourScreenTest extends BaseScreenTest {
  late YourService yourService;
  
  YourScreenTest({
    required ApiClient apiClient,
    required GetIt getIt,
    // ... 기타 필수 파라미터
  }) : super(
    apiClient: apiClient,
    getIt: getIt,
    // ... 부모 클래스에 전달
  );
}
```

### 2. 필수 구현 메서드

#### 2.1 메타데이터 정의
```dart
@override
ScreenMetadata getScreenMetadata() {
  return ScreenMetadata(
    screenName: 'YourScreen',
    controllerType: YourService,
    relatedEndpoints: [
      // API 엔드포인트 목록
    ],
    screenCapabilities: {
      'crud': {'create': true, 'read': true, 'update': true, 'delete': true},
      'search': {'enabled': true, 'fields': ['name', 'code']},
      'filter': {'enabled': true, 'fields': ['status', 'type']},
      'pagination': {'enabled': true, 'defaultPerPage': 20},
    },
  );
}
```

#### 2.2 서비스 초기화
```dart
@override
Future<void> initializeServices() async {
  yourService = getIt<YourService>();
}

@override
dynamic getService() => yourService;

@override
String getResourceType() => 'your_resource';

@override
Map<String, dynamic> getDefaultFilters() {
  return {'status': 'active'};
}
```

#### 2.3 CRUD 작업 구현
```dart
@override
Future<dynamic> performCreateOperation(TestData data) async {
  // 실제 생성 로직
  final model = YourModel.fromJson(data.data);
  return await yourService.create(model);
}

@override
Future<dynamic> performReadOperation(TestData data) async {
  // 실제 읽기 로직
  return await yourService.getList(
    page: data.data['page'] ?? 1,
    perPage: data.data['perPage'] ?? 20,
  );
}

@override
Future<dynamic> performUpdateOperation(dynamic resourceId, Map<String, dynamic> updateData) async {
  // 실제 업데이트 로직
  return await yourService.update(resourceId, updateData);
}

@override
Future<void> performDeleteOperation(dynamic resourceId) async {
  // 실제 삭제 로직
  await yourService.delete(resourceId);
}

@override
dynamic extractResourceId(dynamic resource) {
  // 리소스에서 ID 추출
  return resource.id ?? resource['id'];
}
```

### 3. 선택적 구현 메서드

#### 3.1 데이터 검증
```dart
@override
Future<void> validateDataBeforeCreate(TestData data) async {
  // 생성 전 데이터 검증 로직
  if (data.data['name'] == null) {
    throw ValidationError('이름은 필수입니다');
  }
}
```

#### 3.2 업데이트 데이터 준비
```dart
@override
Future<Map<String, dynamic>> prepareUpdateData(TestData data, dynamic resourceId) async {
  // 기본 구현을 사용하거나 커스터마이즈
  final updateData = await super.prepareUpdateData(data, resourceId);
  // 추가 로직
  return updateData;
}
```

#### 3.3 추가 설정/정리
```dart
@override
Future<void> performAdditionalSetup() async {
  // 화면별 추가 설정
}

@override
Future<void> performAdditionalCleanup() async {
  // 화면별 추가 정리
}
```

### 4. 커스텀 기능 테스트
```dart
@override
Future<List<TestableFeature>> detectCustomFeatures(ScreenMetadata metadata) async {
  final features = <TestableFeature>[];
  
  features.add(TestableFeature(
    featureName: 'Custom Feature',
    type: FeatureType.custom,
    testCases: [
      TestCase(
        name: 'Custom test case',
        execute: (data) async {
          // 커스텀 테스트 실행
        },
        verify: (data) async {
          // 커스텀 테스트 검증
        },
      ),
    ],
  ));
  
  return features;
}
```

## 자동 에러 처리

### 1. 에러 진단
- API 에러 자동 분석
- 에러 타입 식별 (필수 필드 누락, 잘못된 참조, 권한 오류 등)
- 신뢰도 기반 자동 수정 시도

### 2. 자동 수정 액션
- `updateField`: 필드 값 자동 수정
- `createMissingResource`: 누락된 참조 데이터 자동 생성
- `retryWithDelay`: 지연 후 재시도

### 3. 재시도 로직
- 백오프를 포함한 자동 재시도
- 최대 3회 시도 (설정 가능)
- 점진적 지연 시간 증가

## 병렬 테스트 실행

### 1. 세션 격리
- 각 테스트는 고유한 세션 ID를 가짐
- 리소스 충돌 방지

### 2. 리소스 잠금
```dart
// 필요시 리소스 잠금 사용
await _acquireLock('critical_resource');
try {
  // 중요한 작업 수행
} finally {
  _releaseLock('critical_resource');
}
```

## 테스트 데이터 관리

### 1. 자동 생성
- TestDataGenerator를 통한 현실적인 테스트 데이터 생성
- 관계 데이터 자동 생성

### 2. 자동 정리
- 테스트 종료 시 생성된 모든 데이터 자동 삭제
- 역순 삭제로 참조 무결성 보장

## 리포트 생성

### 1. 자동 로깅
- 모든 작업이 자동으로 로깅됨
- 성공/실패 상태 추적

### 2. 상세 리포트
- 각 기능별 테스트 결과
- 에러 진단 및 수정 내역
- 성능 메트릭

## 예제

전체 구현 예제는 `example_screen_test.dart` 파일을 참조하세요.

## 주의사항

1. **서비스 메서드 규약**: 서비스는 다음 메서드를 구현해야 합니다:
   - `create(model)`
   - `getList(page, perPage)`
   - `getById(id)`
   - `update(id, data)`
   - `delete(id)`
   - `search(keyword)` (검색 기능 사용 시)
   - `getListWithFilters(filters)` (필터 기능 사용 시)

2. **데이터 모델**: TestData의 data 필드는 Map<String, dynamic> 형식입니다.

3. **병렬 실행**: 병렬 테스트 시 리소스 경쟁을 피하기 위해 고유한 데이터를 사용하세요.

4. **에러 처리**: 예상되는 에러는 적절히 처리하고, 예상치 못한 에러만 throw하세요.