2021/3/20 : Flutter : An introduction to widget testingの訳

null safety article

An introduction to widget testing

In the introduction to unit testing recipe, you learned how to test Dart classes using the test package. To test widget classes, you need a few additional tools provided by the flutter_test package, which ships with the Flutter SDK.

introduction to unit testingレシピで、Dartのクラスをtestパッケージを使ってテストする方法を学びました。widgetクラスをテストする場合、flutter_testパッケージで提供されているいくつかの新しいツールが必要になります。

これはFlutterSDKに付属しています。

 

The flutter_test package provides the following tools for testing widgets:

flutter_testパッケージはwedgetテスト用の下記のツールを提供します。

  • The WidgetTester allows building and interacting with widgets in a test environment.

WidgetTesterクラス:テスト環境でウィジェットをビルド・インタラクトを可能にする。

 

  • The testWidgets() function automatically creates a new WidgetTester for each test case, and is used in place of the normal test() function.

testWidgets()関数は自動的に新しいWidgetTesterを各テストケースで生成してくれます。そしてtestWidgets()関数はtest()関数の中で使うことができます。

 

  • The Finder classes allow searching for widgets in the test environment.

Finderクラスを使うとテスト環境で特定のwidgetを探すことができます。

 

  • Widget-specific Matcher constants help verify whether a Finder locates a widget or multiple widgets in the test environment.

Widget固有のMatcher定数を使って、テスト環境においてFinderの結果(特定のWidgetの存在の有無など)を確認することができます。

 

If this sounds overwhelming, don’t worry. Learn how all of these pieces fit together throughout this recipe, which uses the following steps:

よくわからないかもしれませんが、心配は無用です。これらの要素全てをどのように使うか、このレシピで学んでいきます。

1.Add the flutter_test dependency.

flutter_testパッケージ(依存関係)をpubspec.yamlファイルに追加します。

 

2.Create a widget to test.

テスト対象のwidgetを用意します。

 

3.Create a testWidgets test.

テスト(testWidgets関数)を定義します。

 

4.Build the widget using the WidgetTester.

WidgetTesterを使ってwidgetをビルドします。

 

5.Search for the widget using a Finder.

Finderを使ってwidgetを探します。

 

6.Verify the widget using a Matcher.

Matcherを使ってwidgetの有無を確認します。


1. Add the flutter_test dependency

Before writing tests, include the flutter_test dependency in the dev_dependencies section of the pubspec.yaml file.

テストの前に、flutter_testパッケージ(依存関係)をpubspec.yamlファイルのdev_dependenciesセクションに追加します。

 

If creating a new Flutter project with the command line tools or a code editor, this dependency should already be in place.

コマンドラインツールまたはコードエディターを使用して新しいFlutterプロジェクトを作成する場合、この依存関係はすでに存在しているはずです。

dev_dependencies:
  flutter_test:
    sdk: flutter

 


2. Create a widget to test

Next, create a widget for testing. For this recipe, create a widget that displays a title and message.

テスト対象のwidgetを定義します。今回のレシピではtitleとmessageを表示するMyWidgetウィジェットを定義します。

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

  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. Create a testWidgets test

With a widget to test, begin by writing your first test.

テスト対象のwidgetを用意したので、初めてのテストを書いていきましょう。

 

Use the testWidgets() function provided by the flutter_test package to define a test.

flutter_testパッケージで提供されているtestWidgets()関数を使ってテストを定義していきます。

 

The testWidgets function allows you to define a widget test and creates a WidgetTester to work with.

testWidgets関数を使えば、自動的にWidgetTesterが用意されて、widgetテストを定義することができます。

 

This test verifies that MyWidget displays a given title and message. It is titled accordingly, and it will be populated in the next section.

このテストでは、MyWidgetウィジェットが、与えられたtitleとmessageを表示できるかを確認します。

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関数によりWidgetTesterが使えるようになります。
  //WidgetTesterを使えばテスト環境でテスト対象widgetを構築してインタラクトすることができます。
  testWidgets('MyWidget has a title and message', (WidgetTester tester) async {
    // Test code goes here.
    //ここにテストコードを書いていきます。
  });
}

 


4. Build the widget using the WidgetTester

Next, build MyWidget inside the test environment by using the pumpWidget() method provided by WidgetTester.

次に、テスト環境にMyWidgetウィジェットを構築します。そのためにWidgetTesterクラスが提供するpumpWidget()メソッドを使います。

 

The pumpWidget method builds and renders the provided widget.

pumpWidgetメソッドは、与えられたウィジェット(今回のサンプルではMyWidget)を構築(ビルド)・レンダーすることができます。

 

Create a MyWidget instance that displays “T” as the title and “M” as the message.

タイトルとして”T”、メッセージとして”M”を表示するMyWidgetインスタンスを生成します。
void main() {
  testWidgets('MyWidget has a title and message', (WidgetTester tester) async {
    // Create the widget by telling the tester to build it.
    await tester.pumpWidget(MyWidget(title: 'T', message: 'M'));
  });
}

 

Notes about the pump() methods

After the initial call to pumpWidget(), the WidgetTester provides additional ways to rebuild the same widget.

最初のpumpWidget()の呼び出しの後、WidgetTesterは同じウィジェットをリビルドするための方法を提供します。

 

This is useful if you’re working with a StatefulWidget or animations.

StatefulWidgetやアニメーションのテストを扱う場合に使えます。

 

For example, tapping a button calls setState(), but Flutter won’t automatically rebuild your widget in the test environment.

例えば、ボタンを押すとsetState()が呼び出されるようなウィジェットでも、テスト環境ではFlutterは自動的にリビルドしません。

 

Use one of the following methods to ask Flutter to rebuild the widget.

次のいずれかの方法を使用して、Flutterにウィジェットの再構築(リビルド)を依頼します。


tester.pump(Duration duration)

Schedules a frame and triggers a rebuild of the widget.

フレームをスケジュールし、ウィジェットの再構築をトリガーします。

 

If a Duration is specified, it advances the clock by that amount and schedules a frame.

Durationを指定すると、その分だけクロックが進み、フレームがスケジュールされます。

 

It does not schedule multiple frames even if the duration is longer than a single frame.

期間が単一フレームより長くても、複数のフレームをスケジュールしません。

 

Note:アニメーションを開始するには、ティッカーを開始するために1回(duration(アーギュメント・引数)を指定せずに)pump()メソッドを呼び出す必要があります。これがないと、アニメーションは開始されません。


tester.pumpAndSettle()

Repeatedly calls pump() with the given duration until there are no longer any frames scheduled.

スケジュールされたフレームがなくなるまで、指定された期間で繰り返しpump()メソッドを呼び出します

 

This, essentially, waits for all animations to complete.

これは、基本的に、すべてのアニメーションが完了するのを待ちます。

 

These methods provide fine-grained control over the build lifecycle, which is particularly useful while testing.

これらのメソッドは、ビルドライフサイクルをきめ細かく制御します。これは、特にテスト中に役立ちます。


5. Search for our widget using a Finder

With a widget in the test environment, search through the widget tree for the title and message Text widgets using a Finder.

Finderを使って、テスト環境のウィジェットツリーの中からtitleとmessageのテキストウィジェットを探し出します。

 

This allows verification that the widgets are being displayed correctly.

これはウィジェットが正しく表示されることを確認することができる、ということです。

 

For this purpose, use the top-level find() method provided by the flutter_test package to create the Finders.

flutter_testパッケージで提供されているトップレベルのfind()メソッドを使ってFinderを生成します。

 

Since you know you’re looking for Text widgets, use the find.text() method.

今はテキストウィジェットを探すので、find.text()メソッドを使います。

 

For more information about Finder classes, see the Finding widgets in a widget test recipe.

Finderクラスについてのさらに詳しい情報は、Finding widgets in a widget test recipe.をご覧ください。

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

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

 


6. Verify the widget using a Matcher

Finally, verify the title and message Text widgets appear on screen using the Matcher constants provided by flutter_test.

最後に、flutter_testパッケージで提供されているMatcher定数を使って、画面に表示されるテキストウィジェット(titleとmessage)を確認します。

 

Matcher classes are a core part of the test package, and provide a common way to verify a given value meets expectations.

Matcherクラスはtestパッケージのコア部分であり、特定の値が期待を満たしていることを確認するための一般的な方法を提供します。

 

Ensure that the widgets appear on screen exactly one time. For this purpose, use the findsOneWidget Matcher.

ウィジェットが画面に一度だけ現れるのを確認します。このために、Matcher定数であるfindsOneWidgetを使います。

void main() {
  testWidgets('MyWidget has a title and message', (WidgetTester tester) async {
    await tester.pumpWidget(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. 
    //findsOneWidgetマッチャーを使って、テキストウィジェットが正確に一度だけウィジェット
    //ツリーに現れることを確認します。
    expect(titleFinder, findsOneWidget);
    expect(messageFinder, findsOneWidget);
  });
}

Additional Matchers

findsOneWidget以外にも、flutter_testには一般的なケースに対応するマッチャーが用意されています。

findsNothing

Verifies that no widgets are found.

widgetが見つからなかったことを確認する。


findsWidgets

Verifies that one or more widgets are found.

一つ、あるいは複数のウィジェットがあることを確認する。


findsNWidgets

Verifies that a specific number of widgets are found.

特定の数のウィジェットがあることを確認する。


matchesGoldenFile
Verifies that a widget’s rendering matches a particular bitmap image (“golden file” testing).
ウィジェットのレンダリングが特定のビットマップイメージと一致することを確認します(「ゴールデンファイル」テスト)。

 

Complete example

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', (WidgetTester 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({
    Key? key,
    required this.title,
    required this.message,
  }) : super(key: key);

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

参考

https://flutter.dev/docs/cookbook/testing/widget/introduction

コメントを残す

メールアドレスが公開されることはありません。