플러터 Testing - Widget(1)

Inyeong Kang·2023년 7월 8일
1
post-thumbnail

Flutter Cookbook 링크

An introduction to widget testing

단위 테스트 레시피 소개에서 test 패키지를 사용하여 Dart 클래스를 테스트하는 방법을 배웠다. 위젯 클래스를 테스트하려면 Flutter SDK와 함께 제공되는 f lutter_test 패키지에서 제공하는 몇 가지 추가 도구가 필요하다.

flutter_test 패키지는 위젯 테스트를 위해 다음과 같은 도구를 제공한다.

  • WidgetTester는 테스트 환경에서 위젯을 빌드하고 상호 작용할 수 있다.
  • testWidgets() 함수는 각 테스트 사례에 대해 자동으로 새 WidgetTester를 생성 하고 일반 test() 함수 대신 사용된다.
  • Finder 클래스를 사용하면 테스트 환경에서 위젯을 검색할 수 있다.
  • 위젯 관련 Matcher 상수는 Finder가 테스트 환경에서 위젯 또는 여러 위젯을 찾는데 도움이 된다.

이것이 압도적으로 들리더라도 걱정하지 마세요. 다음 단계를 사용하는 이 레시피 전체에서 이러한 모든 조각이 어떻게 함께 맞는지 알아보자.

  1. flutter_test 종속성 추가
  2. 테스트할 위젯 생성
  3. testWidgets 테스트 생성
  4. WidgetTester를 사용한 위젯 빌드
  5. Finder를 사용한 위젯 검색
  6. Matcher를 사용한 위젯 확인

1. flutter_test 종속성 추가

테스트를 작성하기 전에 pubspec.yaml 파일의 dev_dependencies 섹션에 flutter_test 종속성을 포함하라. 명령줄 도구 또는 코드 편집기를 사용하여 새 Flutter 프로젝트를 만드는 경우 이 종속성이 이미 설정되어 있어야 한다.

dev_dependencies:
  flutter_test:
    sdk: flutter

2. 테스트할 위젯 생성

다음으로 테스트용 위젯을 만든다. 이 레시피의 경우 title 및 message를 표시하는 위젯을 만든다.

class MyWidget extends StatelessWidget {
  const MyWidget({
    super.key,
    required this.title,
    required this.message,
  });

  final String title;
  final String message;

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: Center(
          child: Text(message),
        ),
      ),
    );
  }
}

3. testWidgets 테스트 생성

테스트할 위젯을 사용하여 첫 번째 테스트 작성을 시작한다. flutter_test 패키지에서 제공하는 testWidgets() 함수를 사용하여 테스트를 정의한다. testWidgets 함수는 위젯 테스트를 정의하고 작업할 WidgetTester을 생성한다.
이 테스트는 MyWidget가 주어진 제목과 메시지를 표시하는지 확인한다. 이에 따라 제목이 지정되며 다음 섹션에서 채워진다.

void main() {
  // Define a test. The TestWidgets function also provides a WidgetTester
  // to work with. The WidgetTester allows you to build and interact
  // with widgets in the test environment.
  testWidgets('MyWidget has a title and message', (tester) async {
    // Test code goes here.
  });
}

4. WidgetTester를 사용할 위젯 빌드

다음으로 WidgetTester에서 제공하는 pumpWidget() 함수를 사용해서 MyWidget를 테스트 환경 내부에 빌드한다. pumpWidget 함수는 제공된 위젯을 빌드하고 렌더링한다.

제목으로 "T"를 표시하고 메시지로 "M"을 표시하는 MyWidget 인스턴스를 만든다.

void main() {
  testWidgets('MyWidget has a title and message', (tester) async {
    // Create the widget by telling the tester to build it.
    await tester.pumpWidget(const MyWidget(title: 'T', message: 'M'));
  });
}

pump() 함수에 대한 참고 사항

pumpWidget()에 대한 초기 호출 후, WidgetTester는 동일한 위젯을 다시 빌드하는 추가 방법을 제공한다. 이것은 StatefulWidget 또는 애니메이션으로 작업하는 경우에 유용하다.

예를 들어 버튼을 탭해서 setState()를 호출 되지만 Flutter는 테스트 환경에서 위젯을 자동으로 다시 빌드하지 않는다. 다음 방법 중 하나를 사용하여 Flutter에 위젯을 다시빌드하도록 요청하라.

tester.pump(Duration duration)
프레임을 예약하고 위젯의 재빌드를 트리거한다. 만약 Duration이 지정되면, 해당 양만큼 시계를 앞당기고 프레임을 예약한다. 기간이 단일 프레임보다 길더라도 여러 프레임을 예약하지 않는다.

참고: 애니메이션을 시작하려면 ticker를 시작하기 위해 pump()를 한 번 호출해야 한다(지정된 기간 없음). 이것이 없으면 애니메이션이 시작되지 않는다.

tester.pumpAndSettle()
더 이상 예약된 프레임이 없을 때까지 지정된 기간으로 pump()를 반복 호출한다. 기본적으로 모든 애니메이션이 완료될 때까지 기다린다.
이러한 메서드는 테스트 중에 특히 유용한 빌드 수명 주기에 대한 세밀한 제어를 제공한다.

5. Finder를 사용한 위젯 검색

테스트 환경의 위젯을 사용하여 위젯 트리에서 Finder를 사용한 title 및 message 텍스트 위젯을 통해 검색한다. 이를 통해 위젯이 올바르게 표시되는지 확인할 수 있다.

이를 위해 Finders를 만드는 flutter_test 패키지에서 제공하는 최상위 find() 함수를 사용하라. Text 위젯을 찾고 있다는 것을 알고 있으므로 이 find.text() 방법을 사용하라.

Finder 클래스에 대한 자세한 내용은 위젯 테스트 레시피에서 위젯 찾기를 참조하라.

void main() {
  testWidgets('MyWidget has a title and message', (tester) async {
    await tester.pumpWidget(const MyWidget(title: 'T', message: 'M'));

    // Create the Finders.
    final titleFinder = find.text('T');
    final messageFinder = find.text('M');
  });
}

6. Matcher를 사용한 위젯 확인

마지막으로 flutter_test에서 제공하는 Matcher 상수를 사용하여 제목 및 메시지 Text 위젯이 화면에 나타나는지 확인한다. Matcher 클래스는 test 패키지의 핵심 부분이며, 주어진 값이 기대치를 충족하는지 확인하는 일반적인 방법을 제공한다.

위젯이 정확히 한 번 화면에 나타나는지 확인하라. 이를 위해 findsOneWidget Matcher를 사용하라.

void main() {
  testWidgets('MyWidget has a title and message', (tester) async {
    await tester.pumpWidget(const MyWidget(title: 'T', message: 'M'));
    final titleFinder = find.text('T');
    final messageFinder = find.text('M');

    // Use the `findsOneWidget` matcher provided by flutter_test to verify
    // that the Text widgets appear exactly once in the widget tree.
    expect(titleFinder, findsOneWidget);
    expect(messageFinder, findsOneWidget);
  });
}

추가 매처

findsOneWidget와 더불어, flutter_test는 일반적인 경우에 대한 추가 매처를 제공한다.

  • findsNothing : 위젯이 없는지 확인
  • findsWidgets : 하나 이상의 위젯이 있는지 확인
  • findsNWidgets : 특정 개수의 위젯이 있는지 확인
  • matchesGoldenFile : 위젯의 렌더링이 특정 비트맵 이미지와 일치하는지 확인("golden file" 테스트).

완전한 예제

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  // Define a test. The TestWidgets function also provides a WidgetTester
  // to work with. The WidgetTester allows building and interacting
  // with widgets in the test environment.
  testWidgets('MyWidget has a title and message', (tester) async {
    // Create the widget by telling the tester to build it.
    await tester.pumpWidget(const MyWidget(title: 'T', message: 'M'));

    // Create the Finders.
    final titleFinder = find.text('T');
    final messageFinder = find.text('M');

    // Use the `findsOneWidget` matcher provided by flutter_test to
    // verify that the Text widgets appear exactly once in the widget tree.
    expect(titleFinder, findsOneWidget);
    expect(messageFinder, findsOneWidget);
  });
}

class MyWidget extends StatelessWidget {
  const MyWidget({
    super.key,
    required this.title,
    required this.message,
  });

  final String title;
  final String message;

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: Center(
          child: Text(message),
        ),
      ),
    );
  }
}
profile
안녕하세요. 강인영입니다. GDSC에서 필요한 것들을 작업하고 업로드하려고 합니다!

0개의 댓글