LoginSignup
18
8

More than 1 year has passed since last update.

【Flutter】Finderまとめ【Widget Test】

Posted at

はじめに

FlutterでWidget Testをする場合、生成したWidget内で「どのWidgetが」「いくつあるのか(ないのか)」をexpectで確かめる。
この 「どのWidgetが」 に当たる部分をFinderで指定する。

例えば、これは公式のWidget Testのドキュメントに書いてあるコードなんだけど、

final titleFinder = find.text('T');
final messageFinder = find.text('M');

expect(titleFinder, findsOneWidget);
expect(messageFinder, findsOneWidget);

'T'と表示しているTextや、'M'と表示しているTextが、生成したWidgetに1つ含まれているかを確認している。
このFinderには結構種類かあって、使い分けることで色んなWidgetをスマートに取得することができる。

この記事では、そんなFlutterのWidget TestにおけるFinderについてまとめるよ。

find.text()

指定した文字列を含むText・EditText・RichTextを探す。

使い方

Text('Pikachu');

expect(find.text('Pikachu'), findsOneWidget);

find.textContaining()

指定したPatternにマッチしたText・EditText・RichTextを探す。
正規表現とかを渡して、柔軟にWidgetを探すことができる。

使い方

Text('Pikachu');

expect(find.textContaining(RegExp(r'^Pika.*')), findsOneWidget);

find.widgetWithText()

指定した文字列を持つ、指定した型のWidgetを探す。
厳密に探せるので使いやすい。

使い方

PokemonName(
    child: Text('Pikachu'),
);

expect(find.widgetWithText(PokemonName, 'Pikachu'), findsOneWidget);

find.image()

指定したimageを含むImage・FadeInImageを探す。

使い方

Image.asset('images/pikachu.png');

expect(find.image(Image.asset('images/pikachu.png').image), findsOneWidget);

find.byKey()

指定したKeyを持つWidgetを探す。
使い道が幅広くて便利。

使い方

Text('Pikachu', key: Key('Pikachu'));

expect(find.byKey(Key('Pikachu')), findsOneWidget);

find.bySubtype()

指定した型のサブクラスのWidgetを探す。
あんま使わなそう。

使い方

abstract class Pokemon extends StatelessWidget {}

class Pikachu extends Pokemon {}

Pikachu();

expect(find.bySubType<Pokemon>(), findsOneWidget);

find.byType()

指定した型のWidgetを探す。
条件でWidgetを出し分けてる時なんかに使える。

使い方

Pikachu();

expect(find.byType(Pikachu), findsOneWidget);

find.byIcon()

指定したiconを持つIconを探す。
もともと入ってるIconsを多用している場合には便利かもしれない。

使い方

Icon(Icons.add);

expect(find.byIcon(Icons.add), findsOneWidget);

find.widgetWithIcon()

指定したIconを持つ、指定した型のWidgetを探す。

使い方

Button(
    child: Icon(Icons.add)
)

expect(find.widgetWithIcon(Button, Icons.add), findsOneWidget);

find.widgetWithImage()

指定したImageを持つ、指定した型のWidgetを探す。

使い方

Pokemon(
    Image.asset('images/pikachu.png'),
);

expect(find.widgetWithImage(Pokemon, Image.asset('images/pikachu.png').image), findsOneWidget);

find.byElementType()

指定したElementの型を持つWidgetを探す。
Elementが何かはここでは触れないよ。

Pikachu();

expect(find.byElementType(Pikachu), findsOneWidget);

find.byWidget()

指定したWidgetを持つWidgetを探す。
同一インスタンスのWidgetを探すので、childに渡したWidgetが表示されてるかどうか確認するために使うんだと思う。

使い方

final nameText = Text('Pikachu');
PokemonName(child: nameText);

expect(find.byWidget(nameText), findsOneWidget);

find.byWidgetPredicate()

自分で指定した条件に合うWidgetを探す。
めちゃくちゃカスタマイズ性能高い。

使い方

Pikachu();

expect(
    find.byWidgetPredicate((widget) {
        return widget is Pokemon;
    }),
    findsOneWidget,
);

find.byTooltip()

指定した文字列を含んだTooltipを持つWidgetを探す。

使い方

FloatingActionButton(
    onPressed() {},
    tooltip: 'pikachu',
);

expect(find.byTooltip('Pikachu'), findsOneWidget);

find.byElementPredicate()

find.byWidgetPredicateのElement版。
※サンプル書くの辛かったので割愛。

find.descendant()

ofで渡したWidgetの子Widgetで、matchingに合うWidgetを探す。

使い方

PokemonList(
    child: Pikachu();
);

expect(
    find.descendant(
        of: find.byType(PokemonList),
        matching: find.byType(Pikachu),
    ),
    findsOneWidget,
);

find.ancestor()

ofで渡したWidgetの親Widgetで、matchingに合うWidgetを探す。

使い方

PokemonList(
    child: Pikachu();
);

expect(
    find.ancestor(
        of: find.byType(Pikachu),
        matching: find.byType(PokemonList),
    ),
    findsOneWidget,
);

find.bySemanticsLabel()

指定した文字列を含んだsemanticsLabelを持つWidgetを探す。

使い方

Image.asset('images/pikachu.png', semanticLabel: 'Pikachu');

expect(
    find.bySemanticsLabel('Pikachu', findsOneWidget)
);

まとめ

  • Finderをいい感じに使い分けることで、スマートにWidgetを取得することができるよ。
  • 実際使用するFinderには偏りがあるので、よく使うやつを覚えておくといいと思う。
  • 色々使ってみて覚えていくといい感じ。

終わり。

18
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
8