【Flutter】テストで、子ウィジェットを取得する方法

FlutterのWidgetテストで、descendantとancestorを使って対象のウィジェットを探す方法。

Markdownで開く

過去の記事(Qiitaから移行)

この記事は公開当時の知識・環境に基づいて書いたものです。現在の仕様に合わせた更新・動作確認は行っておらず、内容の正確性や動作を保証するものではありません。

初出:2022-05-26・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つ見つかってしまいます。 image.png

解決策

ここで、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

← 記録一覧へ戻る