【Flutter】テストで、子ウィジェットを取得する方法
FlutterのWidgetテストで、descendantとancestorを使って対象のウィジェットを探す方法。
過去の記事(Qiitaから移行)
この記事は公開当時の知識・環境に基づいて書いたものです。現在の仕様に合わせた更新・動作確認は行っておらず、内容の正確性や動作を保証するものではありません。
こんなアプリがありました
ソースコードはこちら。
https://github.com/yuchan2215/FlutterTestLearn/blob/master/lib/main.dart
Flutterの初期コードを改造し、1増えるボタンと2増えるボタンがあります。
Card getCard(String title, int addValue, Key key) {
return Card(
key: key, //Keyはここにある!
child: Column(
children: [
Text(title), //引数の文字をタイトルに
OutlinedButton(
onPressed: () {
_incrementCounter(addValue); //カウンターの値を引数の値分増やす
},
child: const Text("ボタン"),)
],
),
);
}
カードはこのような実装で作られています。
問題点
テストを作る際に、find.text("ボタン")してしまうと、2つ見つかってしまいます。

解決策
ここで、KeyはOneButtonとTwoButtonと分かれていますので、find.byKey()を利用して、孫要素であるTextを探してtester.tap()をしてみようと思います。
成果物
https://github.com/yuchan2215/FlutterTestLearn/blob/master/test/widget_test.dart
上記リンクのようなソースコードになりました。
//KeyからWidgetを取得する
var oneButtonParent = find.byKey(const Key("OneButton"));
//ボタンのテキストを取得する
var buttonText = find.text("ボタン");
//親要素から子要素を取得する
var oneButtonText = find.descendant(of: oneButtonParent, matching: buttonText);
一番下のfind.descendantが子孫を取得する部分なのですが、至ってシンプルです。
find.descendant(of: 親要素が含まれるFinder, matching: 探したいものが含まれるFinder)
としてあげることで、親要素の子孫要素から絞り込んだFinderを生成します。
公式ドキュメントはこちら。
https://api.flutter.dev/flutter/flutter_test/CommonFinders/descendant.html
ちなみに逆バージョンで親要素を取得するものもあります。
https://api.flutter.dev/flutter/flutter_test/CommonFinders/ancestor.html