Upgrade to Pro — share decks privately, control downloads, hide ads and more …

(Flutterテストの)沼にハマってやってみた

daimarom
August 28, 2023

 (Flutterテストの)沼にハマってやってみた

daimarom

August 28, 2023
Tweet

More Decks by daimarom

Other Decks in Programming

Transcript

  1. Flutter におけるテスト(おさらい) unit test A unit test tests a single

    function, method, or class. widget test A widget test (in other UI frameworks referred to as component test) tests a single widget. integration test An integration test tests a complete app or a large part of an app. Testing & debugging > Testing Flutter apps - https://docs.flutter.dev/testing/overview
  2. unit test 単一の関数・メソッド・クラスを対象としたテスト 外部依存は mockito などを用いてモックしたりする ダミーデータは data_fixture_dart や json

    ファイルを用意することが多い 様々な条件下でのロジックを検証する pub.dev > mockito - https://pub.dev/packages/mockito
  3. widget test 単一のウィジェットを対象としたテスト a.k.a component test UIが期待通りに表示されることや、ユーザーインタラクションに応じた検証 golden test もここに含まれる

    実際の UI system と比較すると簡略化される 状態変化に応じたリビルドのため WidgetTester# pump を呼んだり、 WidgetTester#pumpAndSettle を呼んだりする pub.dev > golden_toolkit - https://pub.dev/packages/golden_toolkit
  4. widget test が役立ちそうなとき 通信結果に応じて、表示分岐がある 通信成功時 通信中 通信失敗時 ユーザー操作などに応じた、表示分岐のあるウィジェット UI Stackに基づいたものなど(Ideal,

    Empty, Error, Partial, Loading) 環境起因の表示分岐(言語、ダークモード、レイアウト倍率) 実機、エミュレータ・シミュレータを使わずに実行され高速なため、頻繁に行い たい検証に有効
  5. テストを効率化するために いずれのテストにおいても、特に integration test などにおいて、テストのメンテナ ンスコストを下げることは重要 テストに役立つパッケージの導入 data_fixture_dart によってダミーデータのパターン生成を簡便化 Riverpod

    を介したモックオブジェクトによる差し替え given_when_then や Robot パターンによるテストコードの意図と実装の分離 テスト種別ごとに適当と思われるスパンでの自動実行を行う unit < widget < integration <= e2e でテストのメンテナンスコストは高まるが、スコ ープは広がる&コードへの依存度が下がることを理解し活用する 採用プロダクトにおいて、どういったスコープのテストが重要なのか検討し て適用する
  6. E2E(End to End) test の今までとこれから E2Eテストのハードル テスト作成コストの高さ メンテナンスコストも高い 非エンジニアにとってのハードル Maestro,

    MagicPod のような、テストのメンテナンスコストを比較的小さく抑えられる フレームワークの台頭 非エンジニアでも作成可能 従来のE2Eテストフレームワークに比べ、テストのメンテナンスが容易 E2Eフレームワーク導入によるコストと、E2Eテストを用意しなかったときの人件 費(テスターなど)を考えてみると、割に合うケースが増えてきているかも
  7. UI testing framework 'Maestro' Android/iOS/Flutter/ReactNative をサポート yaml でテストフローを定義(Maestro では Flow

    と呼称) Flow から Flow の呼び出しが可能 ローカル実行可能、CIツール連携も可能(Maestro Cloud) iOS実機で動作しない(シミュレータのみ。 Flutterでは Semantics による wrap か、 scemanticLabel の設定が必要 Semantics( label: "My Label", child: SomeView() ) Maestro by mobile.dev > PLATFORM SUPPORT > Flutter - https://maestro.mobile.dev/platform-support/flutter
  8. 試してみましょう シナリオ:Android の連絡帳アプリを起動し、新しい連絡先を登録してみる appId: com.android.contacts --- - launchApp - tapOn:

    "Create new contact" - tapOn: "First name" - inputRandomPersonName - tapOn: "Last name" - inputRandomPersonName - tapOn: "Phone" - inputRandomNumber: length: 10 - back - tapOn: "Email" - inputRandomEmail - tapOn: "Save"