Flutter/ TDD 개발 간단한 앱으로 실습해보기

koeyhoyh·2022년 8월 24일
2

App_Flutter

목록 보기
17/19

간단한 App을 TDD 방식으로 만들면서 실습 해보겠습니다.

만들 앱은 해당 요구사항을 가지고 있습니다.

  1. AppBar를 가지고 있고 AppBar에는 ‘test’라는 문구와 아이콘이 있다.
  2. 가운데에 ‘test용 앱입니다.’ 라는 문구가 적혀있다.
  3. 밑에 Elevated button이 있으며, ‘happy’ text 와 아이콘을 가지고 있다.

1번 요구사항

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이라는 커다란 위젯 트리 안에서 만들어진 것이기 때문이라고 추측했다.

처음 Material App이 여러 개 나온 이유 (2개)

구조가 잘못되어 있었다.

그 결과

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번 요구사항

2번 요구사항을 위해 테스트 코드를 추가했다.

expect(find.text('test용 앱입니다.'), findsOneWidget);

해결

body: const Center(
          child: Text('test용 앱입니다.'),
        ),

3번 요구사항

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

  • ElevatedButton
    왜 안되는지는 찾아보고 이유를 올리도록 하겠습니다. 죄송합니다.😢

빌드 결과:

profile
내가 만들어낸 것들로 세계에 많은 가치를 창출해내고 싶어요.

0개의 댓글