- 모든 서비스 메서드 시그니처를 실제 구현에 맞게 수정 - 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
13 KiB
13 KiB
Real API 자동화 테스트 프레임워크 - 클래스 다이어그램
1. 클래스 다이어그램
classDiagram
%% Core Framework
class ScreenTestFramework {
<<abstract>>
#TestContext testContext
#ApiErrorDiagnostics errorDiagnostics
#AutoFixer autoFixer
#TestDataGenerator dataGenerator
#ReportCollector reportCollector
+detectFeatures(ScreenMetadata) Future~List~TestableFeature~~
+executeTests(List~TestableFeature~) Future~TestResult~
+handleError(TestError) Future~void~
+generateReport() Future~TestReport~
#detectCustomFeatures(ScreenMetadata)* Future~List~TestableFeature~~
#performCRUD()* Future~void~
}
class ApiErrorDiagnostics {
<<abstract>>
-DiagnosticsManager diagnosticsManager
-Map~String,ErrorPattern~ learnedPatterns
+diagnose(ApiError) Future~ErrorDiagnosis~
+analyzeRootCause(ErrorDiagnosis) Future~RootCause~
+suggestFixes(RootCause) Future~List~FixSuggestion~~
+learnFromError(ApiError, FixResult) Future~void~
}
class AutoFixer {
<<abstract>>
-TestContext testContext
-RetryHandler retryHandler
-List~FixHistory~ fixHistory
+attemptFix(FixSuggestion) Future~FixResult~
+validateFix(FixResult) Future~bool~
+rollback(FixResult) Future~void~
+recordFix(FixResult) Future~void~
#performCustomValidation(FixResult)* Future~bool~
}
class TestDataGenerator {
<<abstract>>
-ValidationManager validationManager
-Map~Type,GenerationStrategy~ strategies
-Map~String,TestData~ generatedData
+determineStrategy(DataRequirement) Future~GenerationStrategy~
+generate(GenerationStrategy) Future~TestData~
+validate(TestData) Future~bool~
+generateRelated(DataRelationship) Future~Map~String,TestData~~
}
%% Infrastructure
class TestContext {
-Map~String,dynamic~ data
-Map~String,List~String~~ createdResources
-Map~String,dynamic~ config
-String currentScreen
+getData(String) dynamic
+setData(String, dynamic) void
+addCreatedResourceId(String, String) void
+getCreatedResourceIds() Map~String,List~String~~
+recordFix(FixResult) void
}
class ReportCollector {
-List~TestResult~ results
-ReportConfiguration config
+collect(TestResult) Future~void~
+generateReport() Future~TestReport~
+exportHtml(TestReport) Future~String~
+exportJson(TestReport) Future~String~
}
%% Support
class DiagnosticsManager {
+checkTokenStatus() Future~Map~String,dynamic~~
+checkPermissions() Future~Map~String,dynamic~~
+validateSchema(Map~String,dynamic~) Future~Map~String,dynamic~~
+checkConnectivity() Future~Map~String,dynamic~~
+checkServerHealth() Future~Map~String,dynamic~~
+savePattern(ErrorPattern) Future~void~
}
class RetryHandler {
-int maxAttempts
-Duration backoffDelay
+retry~T~(Function, {maxAttempts, backoffDelay}) Future~T~
-calculateDelay(int) Duration
}
class ValidationManager {
-Map~Type,Schema~ schemas
+validate(Map~String,dynamic~, Type) Future~bool~
+validateField(String, dynamic, FieldConstraint) bool
+getValidationErrors(Map~String,dynamic~, Type) List~String~
}
%% Screen Tests
class BaseScreenTest {
<<abstract>>
#ApiClient apiClient
#GetIt getIt
+getScreenMetadata()* ScreenMetadata
+initializeServices()* Future~void~
+setupTestEnvironment() Future~void~
+teardownTestEnvironment() Future~void~
+runTests() Future~TestResult~
#getService()* dynamic
#getResourceType()* String
#getDefaultFilters()* Map~String,dynamic~
}
class LicenseScreenTest {
-LicenseService licenseService
+getScreenMetadata() ScreenMetadata
+initializeServices() Future~void~
+detectCustomFeatures(ScreenMetadata) Future~List~TestableFeature~~
+performExpiryCheck(TestData) Future~void~
+performLicenseRenewal(TestData) Future~void~
+performBulkImport(TestData) Future~void~
}
class EquipmentScreenTest {
-EquipmentService equipmentService
+getScreenMetadata() ScreenMetadata
+initializeServices() Future~void~
+detectCustomFeatures(ScreenMetadata) Future~List~TestableFeature~~
+performStatusTransition(TestData) Future~void~
+performBulkTransfer(TestData) Future~void~
}
class WarehouseScreenTest {
-WarehouseService warehouseService
+getScreenMetadata() ScreenMetadata
+initializeServices() Future~void~
+detectCustomFeatures(ScreenMetadata) Future~List~TestableFeature~~
+performCapacityCheck(TestData) Future~void~
+performInventoryReport(TestData) Future~void~
}
%% Models
class TestableFeature {
+String featureName
+FeatureType type
+List~TestCase~ testCases
+Map~String,dynamic~ metadata
}
class TestCase {
+String name
+Function execute
+Function verify
+Function setup
+Function teardown
}
class TestResult {
+String screenName
+DateTime startTime
+DateTime endTime
+List~FeatureTestResult~ featureResults
+List~TestError~ errors
+calculateMetrics() void
}
class ErrorDiagnosis {
+ErrorType type
+String description
+Map~String,dynamic~ context
+double confidence
+List~String~ affectedEndpoints
}
class FixSuggestion {
+String fixId
+FixType type
+String description
+List~FixAction~ actions
+double successProbability
}
%% Relationships
ScreenTestFramework o-- TestContext
ScreenTestFramework o-- ApiErrorDiagnostics
ScreenTestFramework o-- AutoFixer
ScreenTestFramework o-- TestDataGenerator
ScreenTestFramework o-- ReportCollector
BaseScreenTest --|> ScreenTestFramework
LicenseScreenTest --|> BaseScreenTest
EquipmentScreenTest --|> BaseScreenTest
WarehouseScreenTest --|> BaseScreenTest
ApiErrorDiagnostics o-- DiagnosticsManager
AutoFixer o-- RetryHandler
TestDataGenerator o-- ValidationManager
ScreenTestFramework ..> TestableFeature : creates
TestableFeature o-- TestCase
ScreenTestFramework ..> TestResult : produces
ApiErrorDiagnostics ..> ErrorDiagnosis : produces
ApiErrorDiagnostics ..> FixSuggestion : suggests
2. 패키지 구조
graph TD
subgraph "framework"
subgraph "core"
STF[ScreenTestFramework]
AED[ApiErrorDiagnostics]
AF[AutoFixer]
TDG[TestDataGenerator]
end
subgraph "infrastructure"
TC[TestContext]
DC[DependencyContainer]
RC[ReportCollector]
end
subgraph "support"
RH[RetryHandler]
VM[ValidationManager]
DM[DiagnosticsManager]
end
subgraph "models"
TM[test_models.dart]
EM[error_models.dart]
RM[report_models.dart]
end
end
subgraph "screens"
subgraph "base"
BST[BaseScreenTest]
end
subgraph "license"
LST[LicenseScreenTest]
LTS[LicenseTestScenarios]
end
subgraph "equipment"
EST[EquipmentScreenTest]
ETS[EquipmentTestScenarios]
end
subgraph "warehouse"
WST[WarehouseScreenTest]
WTS[WarehouseTestScenarios]
end
end
subgraph "reports"
subgraph "generators"
HRG[HtmlReportGenerator]
JRG[JsonReportGenerator]
end
subgraph "templates"
RT[ReportTemplate]
end
end
3. 주요 디자인 패턴
3.1 Template Method Pattern
abstract class ScreenTestFramework {
// 템플릿 메서드
Future<TestResult> executeTests(List<TestableFeature> features) async {
// 1. 준비
await setupTestEnvironment();
// 2. 실행
for (final feature in features) {
await executeFeatureTests(feature);
}
// 3. 정리
await teardownTestEnvironment();
return generateReport();
}
// 하위 클래스에서 구현
Future<void> setupTestEnvironment();
Future<void> teardownTestEnvironment();
}
3.2 Strategy Pattern
// 전략 인터페이스
abstract class DiagnosticRule {
bool canHandle(ApiError error);
Future<ErrorDiagnosis> diagnose(ApiError error);
}
// 구체적인 전략들
class AuthenticationDiagnosticRule implements DiagnosticRule {
@override
bool canHandle(ApiError error) => error.type == ErrorType.authentication;
@override
Future<ErrorDiagnosis> diagnose(ApiError error) async {
// 인증 관련 진단 로직
}
}
class NetworkDiagnosticRule implements DiagnosticRule {
@override
bool canHandle(ApiError error) => error.type == ErrorType.network;
@override
Future<ErrorDiagnosis> diagnose(ApiError error) async {
// 네트워크 관련 진단 로직
}
}
3.3 Builder Pattern
class TestReportBuilder {
TestReport _report;
TestReportBuilder withSummary(TestSummary summary) {
_report.summary = summary;
return this;
}
TestReportBuilder withScreenReports(List<ScreenTestReport> reports) {
_report.screenReports = reports;
return this;
}
TestReportBuilder withErrorAnalyses(List<ErrorAnalysis> analyses) {
_report.errorAnalyses = analyses;
return this;
}
TestReport build() => _report;
}
3.4 Observer Pattern
abstract class TestEventListener {
void onTestStarted(TestCase testCase);
void onTestCompleted(TestCaseResult result);
void onTestFailed(TestError error);
}
class TestEventNotifier {
final List<TestEventListener> _listeners = [];
void addListener(TestEventListener listener) {
_listeners.add(listener);
}
void notifyTestStarted(TestCase testCase) {
for (final listener in _listeners) {
listener.onTestStarted(testCase);
}
}
}
4. 확장 포인트
4.1 새로운 화면 추가
class NewScreenTest extends BaseScreenTest {
@override
ScreenMetadata getScreenMetadata() {
// 화면 메타데이터 정의
}
@override
Future<List<TestableFeature>> detectCustomFeatures(ScreenMetadata metadata) async {
// 화면별 커스텀 기능 정의
}
}
4.2 새로운 진단 룰 추가
class CustomDiagnosticRule implements DiagnosticRule {
@override
bool canHandle(ApiError error) {
// 처리 가능 여부 판단
}
@override
Future<ErrorDiagnosis> diagnose(ApiError error) async {
// 진단 로직 구현
}
}
4.3 새로운 수정 전략 추가
class CustomFixStrategy implements FixStrategy {
@override
Future<FixResult> apply(FixContext context) async {
// 수정 로직 구현
}
}
5. 사용 예제
// 테스트 실행
void main() async {
// 의존성 설정
final testContext = TestContext();
final errorDiagnostics = ConcreteApiErrorDiagnostics(
diagnosticsManager: DiagnosticsManager(),
);
final autoFixer = ConcreteAutoFixer(
testContext: testContext,
retryHandler: RetryHandler(),
);
final dataGenerator = ConcreteTestDataGenerator(
validationManager: ValidationManager(),
);
final reportCollector = ReportCollector(
config: ReportConfiguration(
outputDirectory: 'test/reports',
),
);
// 라이선스 화면 테스트
final licenseTest = LicenseScreenTest(
apiClient: ApiClient(),
getIt: GetIt.instance,
testContext: testContext,
errorDiagnostics: errorDiagnostics,
autoFixer: autoFixer,
dataGenerator: dataGenerator,
reportCollector: reportCollector,
);
// 테스트 실행
final result = await licenseTest.runTests();
// 리포트 생성
final report = await reportCollector.generateReport();
print('테스트 완료: ${report.summary.overallSuccessRate}% 성공');
}
6. 성능 최적화 전략
6.1 병렬 실행
- 독립적인 테스트 케이스는 병렬로 실행
- 화면별 테스트는 격리된 환경에서 동시 실행
6.2 리소스 재사용
- API 클라이언트 연결 풀링
- 테스트 데이터 캐싱
- 인증 토큰 재사용
6.3 스마트 재시도
- 지수 백오프 알고리즘
- 에러 타입별 재시도 전략
- 학습된 패턴 기반 빠른 수정
7. 모니터링 및 분석
7.1 실시간 모니터링
- 테스트 진행 상황 대시보드
- 에러 발생 즉시 알림
- 성능 메트릭 실시간 추적
7.2 사후 분석
- 테스트 결과 트렌드 분석
- 에러 패턴 식별
- 성능 병목 지점 발견
8. 결론
이 아키텍처는 다음과 같은 장점을 제공합니다:
- 확장성: 새로운 화면과 기능을 쉽게 추가
- 유지보수성: 명확한 책임 분리와 모듈화
- 안정성: 자동 에러 진단 및 수정
- 효율성: 병렬 실행과 리소스 최적화
- 가시성: 상세한 리포트와 모니터링
SOLID 원칙을 준수하며, 실제 프로덕션 환경에서 안정적으로 운영될 수 있는 구조입니다.