앱 단위·화면·통합 테스트
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
// 구현 확인물 캡처 공용 도구 — 화면군마다 `capture_f*_test.dart` 가 이것을 쓴다.
|
||||
//
|
||||
// **앱 코드를 고치지 않는다.** 앱이 쓰는 위젯과 테마를 그대로 기기 위에 띄우고
|
||||
// 화면마다 PNG 를 한 장씩 뽑는다. `adb shell input` 으로 41 화면을 눌러 다니는
|
||||
// 방식은 이 에뮬레이터에서 한 번 누르는 데 최대 60초가 걸려 재현되지 않았다.
|
||||
//
|
||||
// 화면군을 파일로 나눈 이유 — 한 실행이 중간에 끊기면 드라이버가 그때까지 모은
|
||||
// 캡처를 통째로 잃는다. 군마다 실행을 나누면 한 군이 실패해도 나머지는 남는다.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'package:fancake/core/theme/app_theme.dart';
|
||||
|
||||
/// 캡처 도구 한 벌. `main()` 첫 줄에서 만든다.
|
||||
class Capture {
|
||||
Capture() : binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final IntegrationTestWidgetsFlutterBinding binding;
|
||||
|
||||
/// Android 는 이걸 부르지 않으면 화면을 이미지로 뜨지 못한다.
|
||||
Future<void> prepare() => binding.convertFlutterSurfaceToImage();
|
||||
|
||||
/// 정해진 시간만큼 프레임을 돌린다.
|
||||
///
|
||||
/// `pumpAndSettle` 은 로딩 스피너처럼 끝나지 않는 애니메이션이 하나라도 있으면
|
||||
/// 던진다. 캡처는 그런 화면에서도 나와야 하고, 저장소를 읽고 다시 그리는
|
||||
/// 시간도 필요하므로 고정 프레임 수로 돌린다.
|
||||
Future<void> settle(WidgetTester tester, {int frames = 16}) async {
|
||||
for (var i = 0; i < frames; i++) {
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
}
|
||||
}
|
||||
|
||||
/// 화면 하나를 앱 테마 그대로 띄운다.
|
||||
///
|
||||
/// [tag] 로 키를 준다. **없으면 안 된다** — 같은 종류의 화면을 연달아 띄우면
|
||||
/// Flutter 가 앞 화면의 State 를 그대로 재사용해 새 인자가 무시되고
|
||||
/// 앞 화면이 한 번 더 찍힌다(q1 상세가 q4 상세 자리에 찍히는 식).
|
||||
Future<void> open(WidgetTester tester, String tag, Widget screen) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: buildAppTheme(),
|
||||
darkTheme: buildAppTheme(),
|
||||
themeMode: ThemeMode.dark,
|
||||
home: KeyedSubtree(key: ValueKey(tag), child: screen),
|
||||
),
|
||||
);
|
||||
await settle(tester);
|
||||
}
|
||||
|
||||
Future<void> shot(String name) => binding.takeScreenshot(name);
|
||||
|
||||
/// 띄우고 찍기.
|
||||
Future<void> capture(WidgetTester tester, String name, Widget screen) async {
|
||||
await open(tester, name, screen);
|
||||
await shot(name);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user