간단한 App을 TDD 방식으로 만들면서 실습 해보겠습니다.
만들 앱은 해당 요구사항을 가지고 있습니다.
Test - homePage() 클래스
testWidgets('create homepage', (tester) async {
final testWidget = MaterialApp(
home: homePage(),
);
await tester.pumpWidget(testWidget);
await tester.pumpAndSettle();
});
해결 - homePage() 클래스 생성
import 'package:flutter/material.dart';
void main() {
runApp(homePage());
}
class homePage extends StatelessWidget {
Widget build(BuildContext context) {
return Container();
}
}
Test - appBar에서, test라는 text와 icon이 있는지
testWidgets('create homepage', (tester) async {
final testWidget = MaterialApp(
home: homePage(),
);
await tester.pumpWidget(testWidget);
await tester.pumpAndSettle();
expect(
find.byWidgetPredicate(
(Widget widget) =>
widget is AppBar &&
widget.title == const Text('test') &&
widget.leading == const Icon(Icons.save),
description: 'find AppBar'),
findsOneWidget);
});
실패 (테스트 코드 문제점 발견) - 해당 조건의 위젯을 하나도 찾을 수 없습니다.
import 'package:flutter/material.dart';
void main() {
runApp(homePage());
}
class homePage extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('test'),
leading: const Icon(Icons.save),
)),
);
}
}
실패 (테스트 코드 문제점 발견) - 해당 조건과 맞는 위젯을 하나도 찾을 수 없습니다.
expect(
find.byWidgetPredicate(
(Widget widget) =>
widget is MaterialApp &&
widget.home ==
Scaffold(
appBar: AppBar(
title: const Text('test'),
leading: const Icon(Icons.save),
),
),
description: 'find AppBar'),
findsOneWidget);
});
실제로는 AppBar라는 위젯이 뚝딱 만들어진 것이 아니라 MaterialApp이라는 커다란 위젯 트리 안에서 만들어진 것이기 때문이라고 추측했다.
구조가 잘못되어 있었다.
그 결과
MaterialApp(home: MaterialApp(home: Scaffold(...),),);
와 같은 구조가 되어있었다.
화면의 출력이 아무리 같아도, main.dart에서 만든 Scaffold와 test.dart의 Scaffold는 다른 객체이기 때문이다.
→ 해결 - 해당 코드를 넣어서 AppBar에 text와 Icon이 잘 있는 것을 확인할 수 있었다.
expect(find.widgetWithText(AppBar, 'test'), findsNWidgets(1));
expect(find.widgetWithIcon(AppBar, Icons.save), findsOneWidget);
그러면 1번 요구사항은 해결되었다.
2번 요구사항을 위해 테스트 코드를 추가했다.
expect(find.text('test용 앱입니다.'), findsOneWidget);
해결
body: const Center(
child: Text('test용 앱입니다.'),
),
expect(find.widgetWithText(ElevatedButton, 'happy'), findsOneWidget);
expect(find.widgetWithIcon(ElevatedButton, Icons.dangerous), findsOneWidget);
실패
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Center(child: Text('test용 앱입니다.')),
const SizedBox(
height: 50,
),
ElevatedButton.icon(
icon: const Icon(Icons.dangerous),
label: const Text('happy'),
onPressed: () {})
],
ElevatedButton을 찾으면 될 것이라고 생각했는데, 찾지 못했다.
성공 케이스
expect(find.widgetWithText(Column, 'happy'), findsOneWidget);
expect(find.widgetWithIcon(Column, Icons.dangerous), findsOneWidget);
Column의 자손들이라서 그런지, Column에서 찾아야 나왔다. List<Widget> 형식이라서 그런건지, 아닌지는 잘 모르겠다.
Column