はじめに
こんにちは、TIGの村田です。
Dart/Flutter連載の最終日ということで、今回はFlutterでのウィジェットテストについてご紹介します。
事前準備
環境構築はこちらに沿って実施します。私はmacOSを利用していますが、利用しているOSごとに丁寧に手順が準備されているので、それに従って環境構築を進めればOKです。
本記事の前提となるFlutterのバージョンは 2.0.6
です。
$ flutter --version |
ちなみに今回 channel の設定が stable
となっているんですが、ちょうど1年くらい前(2020.06)に書いたこの記事では、Flutter Web を使うためには channel は beta
である必要がありました。進歩ですね。喜ばしい限りです。
さて、Flutterはコマンドでデフォルトのアプリを作成できてしまうのでさくっと作ります。
flutter create app |
作成された tester ディレクトリの中に入り、早速アプリを立ち上げてみます。起動デバイスはどれでも良いですが、本記事では Flutter web を利用することとします。
cd app |
するとおなじみのデフォルトアプリが立ち上がります。
画面右下の FloatingActionButton を押下すると画面中央のカウンタがインクリメントされていく、というシンプルな作りになっています。
ここまで出来たら事前準備は完了です。
ウィジェットテストを実施する
ここからが本題です。皆さんは Flutter の create コマンドを利用してアプリを作成するとテストのコードも一緒に生成されることをご存知でしょうか?
app |
詳細なディレクトリ構成は割愛しますが、上記のような形で生成されたものの中に test
というディレクトリがあり、その配下に widget_test.dart
というファイルが存在します。
// This is a basic Flutter widget test. |
Flutter のテストは以下のコマンドで実行でき、成功すると All tests passed!
と表示されます。
$ flutter test test/widget_test.dart |
これだけだと何が起きているのか分からないので、テストファイルの中身を順繰りに見ていくことにします。
pubspec.yaml の定義
まず、それとなく実行したテストですが、そもそもテスト実行のためには flutter_test
パッケージが必要となります。
dev_dependencies: |
上記は pubspec.yaml の記載ですが、Flutter の create コマンドを使ってアプリを作成すると自動的にこの依存関係が記載されます。もし自分で pubspec.yaml を書き上げる場合には flutter_test
パッケージへの依存を追記してあげる必要があります。
testWidgets
次にテストファイルの中身を見ていきます。先頭で使用されているのが testWidgets()
という関数です。
void main() { |
これは flutter_test
パッケージで定義されている関数で、ウィジェットテストを実施したい時に使うものです。 WidgetTester
というヘルパークラスが用意されており、実際のテストコードはこの WidgetTester
を活用しつつ記述します。
pumpWidget
次は pumpWidget()
についてです。 testWidgets()
の先頭に登場する関数です。
void main() { |
pumpWidget()
は対象の ウィジェット のインスタンスを生成し、その生成処理が問題なく完了することをチェックします。今回は MyApp
が指定されているので、 main.dart にて StatelessWidget として定義されている MyApp
がチェック対象です。
pump
pump()
は ウィジェット の再生成を促すメソッドです。通常UI操作により描画対象に変更が加わった際には自動的に ウィジェット が再生成されます。
例えば以下の画面。右下のボタンを2回押下したのですが、画面中央の数字がボタン押下に合わせて増えています。ユーザの操作に合わせて ウィジェット の再生成が行われています。
この自動的な ウィジェット の再生成がテスト実行環境では行われません。そのため、テストコードの中で明示的に ウィジェット 再生成の指示を出す必要があり、それがこの pump()
というわけです。
find
さて、UIコンポーネントを含むテストで一番大変なのは、テスト対象のオブジェクトをテストプログラム上で特定することではないでしょうか? これが簡単にできるように整備されていればいるほどテスタビリティが高いので、個人的にはとてもうれしいポイントです。
find()
は flutter_test
パッケージが提供するトップレベルの関数で、文字やアイコンなどを元に該当する ウィジェット を特定する Finder として機能します。
今回参照しているテストの中でも数箇所で登場します。
// // Verify that our counter starts at 0. |
find.text('0')
というのが Finder で、0
の文字列を含む ウィジェット を ウィジェット ツリーの中から探索します。今回は画面中央に表示されるカウンターがヒットします。
また、 find.byIcon(Icons.add)
ではアイコンを起点に ウィジェット を探索します。今回は画面右下に表示されるプラスマークの書かれた青いボタンがヒットします。
expect
expects()
は Matcher と一緒に用いることで、ウィジェット が期待通りに生成されているか否かを検証します。
今回だとまずは以下の部分。初期描画時は画面中央のカウンターは 0
と表記されているはずです。
// // Verify that our counter starts at 0. |
次に以下の部分。ボタンを1回押下するので、カウンターの数値は 0
から 1
に変わっているはずです。ちなみに、先程記載したようにボタン押下後には ウィジェット 再生成が行われないので pump()
をコールしています。
// // Tap the '+' icon and trigger a frame. |
これでテストファイルの中身はすべて触れることができました。
さいごに
Flutter で実施するウィジェットテストについてご紹介しました。 expect()
を使って期待値との比較を行うのはどのテストフレームワークでも似たようなものと思いますので、 flutter_test
パッケージや WidgetTester
クラスを活用していつものテストを Flutter でもサクッとこなせるようになりたいなと思いました。
Dart/Flutter連載は完走です! 皆様お付き合い頂きありがとうございました。