Files
superport/test/integration/automated/framework/models/test_models.dart
JiWoong Sul 198aac6525
Some checks failed
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
Flutter Test & Quality Check / Build APK (push) Has been cancelled
test: 통합 테스트 오류 및 경고 수정
- 모든 서비스 메서드 시그니처를 실제 구현에 맞게 수정
- TestDataGenerator 제거하고 직접 객체 생성으로 변경
- 모델 필드명 및 타입 불일치 수정
- 불필요한 Either 패턴 사용 제거
- null safety 관련 이슈 해결

수정된 파일:
- test/integration/screens/company_integration_test.dart
- test/integration/screens/equipment_integration_test.dart
- test/integration/screens/user_integration_test.dart
- test/integration/screens/login_integration_test.dart
2025-08-05 20:24:05 +09:00

424 lines
9.8 KiB
Dart

/// 화면 메타데이터
class ScreenMetadata {
final String screenName;
final Type controllerType;
final List<ApiEndpoint> relatedEndpoints;
final Map<String, dynamic> screenCapabilities;
ScreenMetadata({
required this.screenName,
required this.controllerType,
required this.relatedEndpoints,
required this.screenCapabilities,
});
Map<String, dynamic> toJson() => {
'screenName': screenName,
'controllerType': controllerType.toString(),
'relatedEndpoints': relatedEndpoints.map((e) => e.toJson()).toList(),
'screenCapabilities': screenCapabilities,
};
}
/// API 엔드포인트
class ApiEndpoint {
final String path;
final String method;
final String description;
final Map<String, dynamic>? parameters;
final Map<String, dynamic>? headers;
ApiEndpoint({
required this.path,
required this.method,
required this.description,
this.parameters,
this.headers,
});
Map<String, dynamic> toJson() => {
'path': path,
'method': method,
'description': description,
'parameters': parameters,
'headers': headers,
};
}
/// 테스트 가능한 기능
class TestableFeature {
final String featureName;
final FeatureType type;
final List<TestCase> testCases;
final Map<String, dynamic> metadata;
final Type? requiredDataType;
final Map<String, FieldConstraint>? dataConstraints;
TestableFeature({
required this.featureName,
required this.type,
required this.testCases,
required this.metadata,
this.requiredDataType,
this.dataConstraints,
});
}
/// 기능 타입
enum FeatureType {
crud,
search,
filter,
pagination,
authentication,
export,
import,
custom,
}
///
class TestCase {
final String name;
final Future<void> Function(TestData data) execute;
final Future<void> Function(TestData data) verify;
final Future<void> Function(TestData data)? setup;
final Future<void> Function(TestData data)? teardown;
final Map<String, dynamic>? metadata;
TestCase({
required this.name,
required this.execute,
required this.verify,
this.setup,
this.teardown,
this.metadata,
});
}
/// 테스트 데이터
class TestData {
final String dataType;
final dynamic data;
final Map<String, dynamic> metadata;
TestData({
required this.dataType,
required this.data,
required this.metadata,
});
Map<String, dynamic> toJson() => {
'dataType': dataType,
'data': data is Map || data is List ? data : data?.toJson() ?? {},
'metadata': metadata,
};
}
/// 데이터 요구사항
class DataRequirement {
final Type dataType;
final Map<String, FieldConstraint> constraints;
final List<DataRelationship> relationships;
final int quantity;
DataRequirement({
required this.dataType,
required this.constraints,
required this.relationships,
required this.quantity,
});
}
/// 필드 제약조건
class FieldConstraint {
final bool required;
final bool nullable;
final int? minLength;
final int? maxLength;
final num? minValue;
final num? maxValue;
final String? pattern;
final List<dynamic>? allowedValues;
final String? defaultValue;
FieldConstraint({
this.required = true,
this.nullable = false,
this.minLength,
this.maxLength,
this.minValue,
this.maxValue,
this.pattern,
this.allowedValues,
this.defaultValue,
});
}
/// 데이터 관계
class DataRelationship {
final String name;
final Type targetType;
final RelationType type;
final String targetId;
final int? count;
final Map<String, FieldConstraint>? constraints;
DataRelationship({
required this.name,
required this.targetType,
required this.type,
required this.targetId,
this.count,
this.constraints,
});
}
/// 관계 타입
enum RelationType {
oneToOne,
oneToMany,
manyToMany,
}
/// 생성 전략
class GenerationStrategy {
final Type dataType;
final List<FieldGeneration> fields;
final List<DataRelationship> relationships;
final Map<String, dynamic> constraints;
final int? quantity;
GenerationStrategy({
required this.dataType,
required this.fields,
required this.relationships,
required this.constraints,
this.quantity,
});
}
/// 필드 생성 전략
class FieldGeneration {
final String fieldName;
final Type valueType;
final String strategy;
final String? prefix;
final String? format;
final List<dynamic>? pool;
final String? relatedTo;
final List<String>? values;
final dynamic value;
FieldGeneration({
required this.fieldName,
required this.valueType,
required this.strategy,
this.prefix,
this.format,
this.pool,
this.relatedTo,
this.values,
this.value,
});
}
/// 필드 정의
class FieldDefinition {
final String name;
final FieldType type;
final dynamic Function() generator;
final bool required;
final bool nullable;
FieldDefinition({
required this.name,
required this.type,
required this.generator,
this.required = true,
this.nullable = false,
});
}
/// 필드 타입
enum FieldType {
string,
integer,
double,
boolean,
dateTime,
date,
time,
object,
array,
}
/// 테스트 결과
class TestResult {
final String screenName;
final DateTime startTime;
DateTime? endTime;
final List<FeatureTestResult> featureResults = [];
final List<TestError> errors = [];
final Map<String, dynamic> metrics = {};
TestResult({
required this.screenName,
required this.startTime,
this.endTime,
});
bool get success => errors.isEmpty && featureResults.every((r) => r.success);
bool get passed => success; // 호환성을 위한 별칭
Duration get duration => endTime != null
? endTime!.difference(startTime)
: Duration.zero;
// 테스트 카운트 관련 getter들
int get totalTests => featureResults
.expand((r) => r.testCaseResults)
.length;
int get passedTests => featureResults
.expand((r) => r.testCaseResults)
.where((r) => r.success)
.length;
int get failedTests => totalTests - passedTests;
void calculateMetrics() {
metrics['totalFeatures'] = featureResults.length;
metrics['successfulFeatures'] = featureResults.where((r) => r.success).length;
metrics['failedFeatures'] = featureResults.where((r) => !r.success).length;
metrics['totalTestCases'] = featureResults
.expand((r) => r.testCaseResults)
.length;
metrics['successfulTestCases'] = featureResults
.expand((r) => r.testCaseResults)
.where((r) => r.success)
.length;
metrics['averageDuration'] = _calculateAverageDuration();
}
double _calculateAverageDuration() {
final allDurations = featureResults
.expand((r) => r.testCaseResults)
.map((r) => r.duration.inMilliseconds);
if (allDurations.isEmpty) return 0;
return allDurations.reduce((a, b) => a + b) / allDurations.length;
}
Map<String, dynamic> toJson() => {
'screenName': screenName,
'success': success,
'startTime': startTime.toIso8601String(),
'endTime': endTime?.toIso8601String(),
'duration': duration.inMilliseconds,
'featureResults': featureResults.map((r) => r.toJson()).toList(),
'errors': errors.map((e) => e.toJson()).toList(),
'metrics': metrics,
};
}
/// 기능 테스트 결과
class FeatureTestResult {
final String featureName;
final DateTime startTime;
DateTime? endTime;
final List<TestCaseResult> testCaseResults = [];
final Map<String, dynamic> metrics = {};
FeatureTestResult({
required this.featureName,
required this.startTime,
this.endTime,
});
bool get success => testCaseResults.every((r) => r.success);
Duration get duration => endTime != null
? endTime!.difference(startTime)
: Duration.zero;
void calculateMetrics() {
metrics['totalTestCases'] = testCaseResults.length;
metrics['successfulTestCases'] = testCaseResults.where((r) => r.success).length;
metrics['failedTestCases'] = testCaseResults.where((r) => !r.success).length;
metrics['averageDuration'] = _calculateAverageDuration();
}
double _calculateAverageDuration() {
if (testCaseResults.isEmpty) return 0;
final totalMs = testCaseResults
.map((r) => r.duration.inMilliseconds)
.reduce((a, b) => a + b);
return totalMs / testCaseResults.length;
}
Map<String, dynamic> toJson() => {
'featureName': featureName,
'success': success,
'startTime': startTime.toIso8601String(),
'endTime': endTime?.toIso8601String(),
'duration': duration.inMilliseconds,
'testCaseResults': testCaseResults.map((r) => r.toJson()).toList(),
'metrics': metrics,
};
}
/// 테스트 케이스 결과
class TestCaseResult {
final String testCaseName;
final bool success;
final Duration duration;
final String? error;
final StackTrace? stackTrace;
final Map<String, dynamic>? metadata;
TestCaseResult({
required this.testCaseName,
required this.success,
required this.duration,
this.error,
this.stackTrace,
this.metadata,
});
Map<String, dynamic> toJson() => {
'testCaseName': testCaseName,
'success': success,
'duration': duration.inMilliseconds,
'error': error,
'stackTrace': stackTrace?.toString(),
'metadata': metadata,
};
}
/// 테스트 에러
class TestError {
final String message;
final StackTrace? stackTrace;
final String? feature;
final DateTime timestamp;
final Map<String, dynamic>? context;
TestError({
required this.message,
this.stackTrace,
this.feature,
required this.timestamp,
this.context,
});
Map<String, dynamic> toJson() => {
'message': message,
'stackTrace': stackTrace?.toString(),
'feature': feature,
'timestamp': timestamp.toIso8601String(),
'context': context,
};
}