138 lines
4.4 KiB
Dart
138 lines
4.4 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:flutter_test/flutter_test.dart' as flutter_test;
|
|
|
|
/// 테스트 환경에서 사용할 유틸리티 함수들을 제공하는 클래스
|
|
class TestUtils {
|
|
/// 테스트 모드 강제 설정 (테스트에서 명시적으로 설정 가능)
|
|
static bool _forceTestMode = false;
|
|
|
|
/// 테스트 모드 강제 설정
|
|
static void setTestMode(bool isTest) {
|
|
_forceTestMode = isTest;
|
|
}
|
|
|
|
/// 현재 테스트 환경인지 확인 (개선된 버전)
|
|
static bool get isInTest {
|
|
// 강제 설정된 경우 해당 값 반환
|
|
if (_forceTestMode) {
|
|
return true;
|
|
}
|
|
|
|
// 다양한 방법으로 테스트 환경 감지 시도
|
|
try {
|
|
// 방법 1: flutter_test 라이브러리의 속성 확인
|
|
return flutter_test.WidgetController.hitTestWarningShouldBeFatal;
|
|
} catch (_) {
|
|
try {
|
|
// 방법 2: 테스트 환경에서만 존재하는 Zone 속성 확인
|
|
return Zone.current['_testZoneSpecification'] != null;
|
|
} catch (_) {
|
|
try {
|
|
// 방법 3: 디버그 모드 확인 (완벽한 방법은 아니지만 대안)
|
|
return kDebugMode;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 테스트용 고정 해시 생성 (테스트에서 예측 가능한 결과를 위해)
|
|
static int _testHashCounter = 0;
|
|
|
|
/// 테스트 환경에서 사용할 예측 가능한 해시 생성
|
|
static String getTestHash() {
|
|
_testHashCounter++;
|
|
final counter = _testHashCounter.toString().padLeft(2, '0');
|
|
return 'test$counter';
|
|
}
|
|
|
|
/// 현재 타이머가 활성화되어 있는지 확인
|
|
/// 테스트 종료 시 !timersPending assertion 실패 원인 추적용
|
|
static bool isTimerPending() {
|
|
try {
|
|
// flutter_test 라이브러리의 테스트 환경에서만 사용 가능
|
|
if (isInTest) {
|
|
// Zone 속성을 통해 타이머 상태 확인 시도
|
|
final zone = Zone.current;
|
|
if (zone['_timerCount'] != null) {
|
|
return zone['_timerCount'] > 0;
|
|
}
|
|
|
|
// 다른 방법으로 타이머 상태 확인 시도
|
|
try {
|
|
// SchedulerBinding을 통해 프레임 스케줄링 상태 확인
|
|
return SchedulerBinding.instance.hasScheduledFrame ||
|
|
SchedulerBinding.instance.transientCallbackCount > 0;
|
|
} catch (_) {
|
|
// 실패 시 기본값 반환
|
|
return false;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
debugPrint('타이머 상태 확인 중 오류: $e');
|
|
}
|
|
}
|
|
|
|
// 테스트 환경이 아니거나 오류 발생 시 기본값 반환
|
|
return false;
|
|
}
|
|
|
|
/// 테스트 환경에서 사용할 예측 가능한 해시 생성 (테스트 파일과의 호환성을 위한 별칭)
|
|
static String generatePredictableHash() {
|
|
return getTestHash();
|
|
}
|
|
|
|
/// 테스트 환경에서 애니메이션을 비활성화하는 위젯
|
|
static Widget disableAnimations({required Widget child}) {
|
|
if (!isInTest) {
|
|
return child;
|
|
}
|
|
|
|
return MediaQuery(
|
|
data: const MediaQueryData(
|
|
textScaleFactor: 1.0,
|
|
platformBrightness: Brightness.light,
|
|
padding: EdgeInsets.zero,
|
|
viewInsets: EdgeInsets.zero,
|
|
devicePixelRatio: 1.0,
|
|
size: Size(800, 600),
|
|
),
|
|
child: AnimatedBuilder(
|
|
animation: const AlwaysStoppedAnimation<double>(1.0),
|
|
builder: (BuildContext context, Widget? child) {
|
|
return child!;
|
|
},
|
|
child: child,
|
|
),
|
|
);
|
|
}
|
|
|
|
/// 테스트 환경에서 안전하게 SnackBar를 표시하는 함수
|
|
static void showSnackBarSafely(BuildContext context, SnackBar snackBar) {
|
|
if (!isInTest) {
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
return;
|
|
}
|
|
|
|
// 테스트 환경에서는 SnackBar 표시 대신 로그만 출력
|
|
debugPrint('테스트 환경에서 SnackBar 표시 (내용: ${snackBar.content})');
|
|
}
|
|
|
|
/// 테스트 환경에서 안전하게 현재 SnackBar를 숨기는 함수
|
|
static void hideCurrentSnackBarSafely(BuildContext context) {
|
|
if (!isInTest) {
|
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
|
return;
|
|
}
|
|
|
|
// 테스트 환경에서는 로그만 출력
|
|
debugPrint('테스트 환경에서 현재 SnackBar 숨김');
|
|
}
|
|
}
|