【Flutter】WidgetTestについてのまとめと参考例

Flutter基礎

flutterでテストを実装することが増え、基本的なWidgetTestについてまとめました。
英語で書かれている記事が多いため、日本語で基礎を学びたい・復習したい方向けです。


概要

公式

An introduction to widget testing
Learn more about widget testing in Flutter.

Widget テストとは

単一のWidgetのUIが期待通りに表示・動作するかをテストする手法です。

Flutterの構造上、以下を担保する必要があります。

  • 複数の子Widgetが正常に動作するか
  • build → update → dispose などのライフサイクルが正しく動作するか

flutter_testパッケージ

Flutter SDK 内に含まれる flutter_test パッケージを使用してテストを実施します。
https://api.flutter.dev/flutter/flutter_test

flutter_testパッケージには以下の機能があります。

  • WidgetTester : Widgetの操作とビルドをテスト環境で許可
  • testWidgets() : テストケースごとにWidgetTesterを自動生成
  • Finder : Widgetをテスト環境で探すクラス
  • Matcher : FinderでWidgetが1つまたは複数あるかを確認する定数

Widgetテストの書き方

1. flutter_testの追加

基本的には、flutterプロジェクト作成時に自動的に追加されています。

dev_dependencies:
  flutter_test:
    sdk: flutter

2. テスト対象のWidget作成

※ すでにテストしたいWidgetがある場合は不要です。

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

  final String title;
  final String message;

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

3. テストコードの作成

testWidget関数を使用しWidget Testすることを定義します。
testWidgets関数によってWidgetTesterを作成し各々のテストを実行できるようにする
 例: tester.pumpWidget()

void main() {
  testWidgets('MyWidget has a title and message', (tester) async {
    // Test code goes here.
  });
}

4. WidgetTesterでWidgetをビルド

  • WidgetTesterが提供している pumpWidget を使用
  • MyWidgetの引数titileに適当な文字列を挿入
  • pumpWidget
    • Widgetをリビルドすることが可能
    • StatefulWidget・アニメーションを使用しているWidgetに有効

別のpumpメソッドば別記事に記載予定。

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'));
  });
}

5. FinderでWidgetを探す

  • Widgetが正しく表示されているか確認
  • findを使用し今回はtextが存在するかサーチ
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でWidgetを検証

  • Mactherを使用してWidgetがスクリーンに存在しているか確認
  • Macther
    • 与えられた値が期待どうりかを確認する
      • findsOneWidgetなら一だけ表示されたか
    • いろんな Matherが別途存在し駆使する
  • expect() は第一引数の値を第二引数の 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');

    // Widgetツリーに一度だけ表示されたかチェック
    expect(titleFinder, findsOneWidget);
    expect(messageFinder, findsOneWidget);
  });
}

まとめ

この記事ではFlutterのWidgetテストの基本的な流れを紹介しました。

  • flutter_testパッケージでテスト環境構築
  • WidgetTesterで描画
  • FinderでWidgetを取得
  • Matcherで期待通りの表示を検証

コメント

タイトルとURLをコピーしました