あなたのテストゲーム


今日、我々は我々のウィジェットを正確にテストするようになるとき、我々により多くの力を与えているFlutterのテストフレームワークによって提供される大きなユーティリティを見に行きます.
非常に多くのウィジェットは非常に単純に使用してテストすることができますfind.byType , find.text and find.byKey . これらの各々は非常に使いやすいです、そして、あなたが選ぶものはあなたがテストしようとしているものに依存するでしょう、しかし、このような基本的なテストが貴重な結果をもたらさない若干のシナリオがあります.
以下のウィジェットを例にとります.
class SampleWidget extends StatelessWidget {
  final bool complete;

  const SampleWidget({required this.complete, Key? key}) : super(key: key);

  @override
  Widget build(context) {
    return complete
        ? Icon(Icons.check_circle, color: AppTheme.strongBlue)
        : Icon(Icons.circle_outlined, color: AppTheme.strongBlue);
  }
}

単純なusecase (アイコン)


個人的には、私は通常、私のすべてのウィジェットをテストしていない、上記は非常に簡単なユースケースのサンプルは、私はそれが非常に基本的ですが、このウィジェット自体はいくつかのロジックをポーズしているが、このウィジェットの中で行われている決定は、それが何の複雑な間、それはテストのための理想的なシナリオを説明する目的で提供されています.
上記のウィジェットでは、私が探すことができるテキストがありません、私は個々のアイコンのためにどんなキーも供給しませんでした、そして、彼らは両方のアイコンです.
テストを書くなら、
    testWidgets('Should render the check_circile_icon', (tester) async {
      await tester.pumpApp(const SampleWidget(complete: true));

      await tester.pumpAndSettle();

      final iconFinder = find.byType(Icon);

      expect(iconFinder, findsOneWidget);
    });

    testWidgets('Should render the circle_outlined icon', (tester) async {
      await tester.pumpApp(const SampleWidget(complete: false));

      await tester.pumpAndSettle();

      final iconFinder = find.byType(Icon);

      expect(iconFinder, findsOneWidget);
    });
彼らは両方とも確かに通過します、そして、1つがカバレッジ報告を見るならば、それも100 %のテスト報道を示します、しかし、全体としてのテストはかなり価値がありません、それが論理を走らせている間、論理は確かに働いています、あなたのテストはこれを証明しません.
あなたがテストを書くために時間を取るつもりである(そして、あなたがそうすることを望む)、テストは常にカバレッジレポートのそれを越えて価値を提供しなければなりません.
ここはどこですfind.byWidgetPredicate 便利になると、同じテストを書くことができますが、一意に個々のアイコンを識別できるようになります.find.byWidgetPredicate 関数の引数としてウィジェットを提供する関数ベースのルックアップです.ウィジェットの属性を使用して、同じウィジェットのユニークなインスタンスを特定することができます.
次の例を見れば、更新しましたiconFinder 利用するfind.byWidgetPredicate 代わりにルックアップfind.byType :
    testWidgets('Should render the circle_outlined icon', (tester) async {
      await tester.pumpApp(const SampleWidget(complete: false));

      await tester.pumpAndSettle();

      final iconFinder = find.byWidgetPredicate(
        (widget) => widget is Icon && widget.icon == Icons.circle_outlined,
      );

      expect(textFinder, findsOneWidget);
    });
ご覧のように、機能体の中では、ウィジェットであるウィジェットを探していますIcon (つまりタイプ比較)と、そのアイコンウィジェットのアイコンプロパティがIconData Icons.circle_outlined .
何らかの理由で、誰かが行って、偽のアイコンをIcons.menu 奇妙な理由でfind.byWidgetPredicate ルックアップは失敗します.我々が使用したならばfind.byType あるいはfind.byKey , 我々がユニークなキーを与えたと仮定して、テストは通過し続けました.
The find.byWidgetPredicate ウィジェットのテスト内のルックアップは、近くの防弾テストを書くことができます.

より良いusecase ( RichText )


上の例は非常に簡単な例でしたが、フラッターの中で、1行のテキストを書きたいのであれば、1つの単語を別のスタイルで表現していて、ボールドやイタリックにしてくださいRichText ウィジェットのシーケンスと一緒にTextSpan 'sは望ましい結果を達成するために.
次の例を挙げます.
        RichText(
        text: TextSpan(
          children: [
            const TextSpan(
              text: "Required",
              style: TextStyle(
                fontWeight: FontWeight.bold,
                color: Colors.black,
              ),
            ),
            TextSpan(
              text: " 70%",
              style: const TextStyle(
                color: Colors.black,
              ),
            ),
          ],
        ),
      )
この特定のウィジェットは実際にはテストしないでしょうが、それはもう一つの大きな例ですfind.byWidgetPredicate より複雑なシナリオで.
    final requiredScoreFinder = find.byWidgetPredicate(
      (widget) =>
          widget is RichText &&
          widget.text.toPlainText().contains("70%"),
    );
上記のウィジェットでは、上記のサンプルのようなものをターゲットにしますRichText ウィジェットは実際にテキストを複数の部分に分割します.find.text は動作しません.
使えますcontains 部分的な検索を行うか、単に厳密な平等を使用することができますが、長い文章のために簡単に含めることができます.
    final requiredScoreFinder = find.byWidgetPredicate(
      (widget) =>
          widget is RichText &&
          widget.text.toPlainText() == "Results 70%",
    );
あなたがうまくいけば、現在見ることができます.find.byWidgetPredicate あなたのテストツールベルトの非常に強力なツールであり、さらに良い、より正確なテストを書くことができます.
私はあなたが面白い、この質問を見つけた場合は、ご質問、コメント、または改善がある場合は、コメントを削除する自由を感じる.をお楽しみくださいフラッターの開発の旅:D
あなたがそれを楽しんだならば、それはものすごいです、そして、あなたが本当にそれが好きであるならばcup of coffee でしょう.
読書ありがとう.
ユニットテストのトピックを実行したい場合は、以下を見てください.