import 'dart:io'; import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:test/test.dart'; import 'screens/equipment/equipment_in_full_test.dart'; /// 장비 입고 화면 전체 기능 자동화 테스트 실행 /// /// 사용법: /// ```bash /// dart test test/integration/automated/run_equipment_in_full_test.dart /// ``` void main() { group('장비 입고 화면 전체 기능 자동화 테스트', () { late EquipmentInFullTest equipmentTest; late DateTime startTime; setUpAll(() async { startTime = DateTime.now(); equipmentTest = EquipmentInFullTest(); debugPrint(''' ╔════════════════════════════════════════════════════════════════╗ ║ 장비 입고 화면 전체 기능 자동화 테스트 ║ ╠════════════════════════════════════════════════════════════════╣ ║ 테스트 항목: ║ ║ 1. 장비 목록 조회 ║ ║ 2. 장비 검색 및 필터링 ║ ║ 3. 새 장비 등록 ║ ║ 4. 장비 정보 수정 ║ ║ 5. 장비 삭제 ║ ║ 6. 장비 상태 변경 ║ ║ 7. 장비 이력 추가 ║ ║ 8. 이미지 업로드 (시뮬레이션) ║ ║ 9. 바코드 스캔 시뮬레이션 ║ ║ 10. 입고 완료 처리 ║ ╚════════════════════════════════════════════════════════════════╝ '''); }); test('모든 장비 입고 기능 테스트 실행', () async { // 테스트 실행 final results = await equipmentTest.runAllTests(); // 실행 시간 계산 final duration = DateTime.now().difference(startTime); // 결과 출력 debugPrint('\n'); debugPrint('═════════════════════════════════════════════════════════════════'); debugPrint(' 테스트 실행 결과'); debugPrint('═════════════════════════════════════════════════════════════════'); debugPrint('총 테스트: ${results['totalTests']}개'); debugPrint('성공: ${results['passedTests']}개'); debugPrint('실패: ${results['failedTests']}개'); debugPrint('성공률: ${(results['passedTests'] / results['totalTests'] * 100).toStringAsFixed(1)}%'); debugPrint('실행 시간: ${_formatDuration(duration)}'); debugPrint('═════════════════════════════════════════════════════════════════'); // 개별 테스트 결과 debugPrint('\n개별 테스트 결과:'); debugPrint('─────────────────────────────────────────────────────────────────'); final tests = results['tests'] as List; for (var i = 0; i < tests.items.length; i++) { final test = tests[i]; final status = test['passed'] ? '✅' : '❌'; final retryInfo = test['retryCount'] > 0 ? ' (재시도: ${test['retryCount']}회)' : ''; debugPrint('${i + 1}. ${test['testName']} - $status$retryInfo'); if (!test['passed'] && test['error'] != null) { debugPrint(' 에러: ${test['error']}'); } } debugPrint('─────────────────────────────────────────────────────────────────'); // 리포트 생성 await _generateReports(results, duration); // 테스트 실패 시 예외 발생 if (results['failedTests'] > 0) { // fail('${results['failedTests']}개의 테스트가 실패했습니다.'); } }, timeout: Timeout(Duration(minutes: 30))); // 충분한 시간 할당 }); } /// 리포트 생성 Future _generateReports(Map results, Duration duration) async { try { final timestamp = DateTime.now().toIso8601String().replaceAll(':', '-'); // JSON 리포트 생성 final jsonReportPath = 'test_reports/equipment_in_full_test_$timestamp.json'; final jsonReportFile = File(jsonReportPath); await jsonReportFile.parent.create(recursive: true); await jsonReportFile.writeAsString( JsonEncoder.withIndent(' ').convert({ 'testName': '장비 입고 화면 전체 기능 테스트', 'timestamp': DateTime.now().toIso8601String(), 'duration': duration.inMilliseconds, 'results': results, }), ); debugPrint('\n📄 JSON 리포트 생성: $jsonReportPath'); // Markdown 리포트 생성 final mdReportPath = 'test_reports/equipment_in_full_test_$timestamp.md'; final mdReportFile = File(mdReportPath); final mdContent = StringBuffer(); mdContent.writeln('# 장비 입고 화면 전체 기능 테스트 리포트'); mdContent.writeln(''); mdContent.writeln('## 테스트 개요'); mdContent.writeln('- **실행 일시**: ${DateTime.now().toLocal()}'); mdContent.writeln('- **소요 시간**: ${_formatDuration(duration)}'); mdContent.writeln('- **환경**: Production API (https://api-dev.beavercompany.co.kr)'); mdContent.writeln(''); mdContent.writeln('## 테스트 결과'); mdContent.writeln('| 항목 | 결과 |'); mdContent.writeln('|------|------|'); mdContent.writeln('| 총 테스트 | ${results['totalTests']}개 |'); mdContent.writeln('| ✅ 성공 | ${results['passedTests']}개 |'); mdContent.writeln('| ❌ 실패 | ${results['failedTests']}개 |'); mdContent.writeln('| 📊 성공률 | ${(results['passedTests'] / results['totalTests'] * 100).toStringAsFixed(1)}% |'); mdContent.writeln(''); mdContent.writeln('## 개별 테스트 상세'); mdContent.writeln(''); final tests = results['tests'] as List; for (var i = 0; i < tests.items.length; i++) { final test = tests[i]; final status = test['passed'] ? '✅ 성공' : '❌ 실패'; mdContent.writeln('### ${i + 1}. ${test['testName']}'); mdContent.writeln('- **상태**: $status'); if (test['retryCount'] > 0) { mdContent.writeln('- **재시도**: ${test['retryCount']}회'); } if (!test['passed'] && test['error'] != null) { mdContent.writeln('- **에러**: `${test['error']}`'); } mdContent.writeln(''); } mdContent.writeln('## 자동 수정 내역'); mdContent.writeln(''); mdContent.writeln('이 테스트는 다음과 같은 자동 수정 기능을 포함합니다:'); mdContent.writeln('- 인증 토큰 만료 시 자동 재로그인'); mdContent.writeln('- 필수 필드 누락 시 기본값 자동 생성'); mdContent.writeln('- API 응답 형식 변경 감지 및 대응'); mdContent.writeln('- 검증 에러 발생 시 데이터 자동 수정'); mdContent.writeln(''); mdContent.writeln('---'); mdContent.writeln('*이 리포트는 자동으로 생성되었습니다.*'); await mdReportFile.writeAsString(mdContent.toString()); debugPrint('📄 Markdown 리포트 생성: $mdReportPath'); } catch (e) { debugPrint('⚠️ 리포트 생성 실패: $e'); } } /// 시간 포맷팅 String _formatDuration(Duration duration) { if (duration.inHours > 0) { return '${duration.inHours}시간 ${duration.inMinutes % 60}분 ${duration.inSeconds % 60}초'; } else if (duration.inMinutes > 0) { return '${duration.inMinutes}분 ${duration.inSeconds % 60}초'; } else { return '${duration.inSeconds}초'; } }