paint-brush
Patrol と Codemagic を使用した Flutter アプリのネイティブ機能のテスト@codemagic
802 測定値
802 測定値

Patrol と Codemagic を使用した Flutter アプリのネイティブ機能のテスト

Codemagic CI/CD9m2023/11/06
Read on Terminal Reader

長すぎる; 読むには

Patrol は、Flutter アプリのネイティブ プラットフォーム機能をテストできる LeanCode の新しいテスト ツールです。 Google および Apple の認証フロー、Web ビューの操作、ライト モードとダーク モードの切り替えなどができるようになりました。この記事では、Codemagic CI/CD ワークフローで Patrol を使用する方法も学習します。
featured image - Patrol と Codemagic を使用した Flutter アプリのネイティブ機能のテスト
Codemagic CI/CD HackerNoon profile picture
0-item
1-item

「役に立たない! Flutter の統合テストではエンドツーエンドのテストを実行できない」と、約 9 か月前、当社の顧客の 1 人が叫びました。何が問題なのか尋ねると、ログインには Google 認証を使用し、 google_sign_inパッケージを使用していましたが、Flutter の統合テストを使用してログイン画面を操作することはできなかったと説明されました。私はまだ問題が何なのかをよく理解していませんでしたが、ピンと来ました。このプラグインは、統合テストでは機能しないネイティブ UI コンポーネントを使用しています。


当時は解決策を提示できず、放置しなければならなかったことが非常に残念でした。しかし、今日に早送りすると、 「パトロール」と呼ばれる素晴らしい新しいソリューションが発表されました。リーンコード。これからすべてを説明しますが、本題に入る前に、テストを実行することがなぜ重要なのか、これまでにどのようなツールが利用できたのかを簡単にまとめてから、Patrol を始める方法について話しましょう。

そもそも、なぜ Flutter アプリをテストするのでしょうか?

開発チームが次のような継続的インテグレーション(CI) サービスを使用する主な理由の 1 つは、コードマジックリポジトリにコミットしているコードに関するフィードバックをすぐに得ることです。テストはパイプラインの一部として自動的に実行され、バグや問題を早期に発見してすぐに修正できるため、品質と安定性の両方のレベルを保証できます。私たちは常に、ワークフローを設定するときにテストを実装することをお客様に推奨していますが、「テストを作成する時間がない」という声を聞くことは珍しいことではありません。あなたがそのような状況に陥っておらず、アプリ開発サイクルの一部としてテストを使用して、高品質でバグのないアプリを提供できることを願っています。

Flutter アプリをテストする主な自動化方法は何ですか?

CI ワークフローの一部として自動化できる主なテスト方法は 4 つあります。テスト自体が重要なトピックなので、簡単に説明しますが、これらのテスト方法を組み合わせて使用すると、アプリの品質を向上させ、問題を早期に発見するのに役立ちます。


まず、 「単体テスト」があります。これは、関数とメソッドを個別にテストして、期待どおりに動作することを確認するために一般的に使用されます。単体テストを作成して、ビジネス ロジックがさまざまなシナリオで予期しない結果が発生することなく動作することを確認することもできます。


次に、Flutter の「ウィジェット テスト」を使用すると、UI コンポーネントをテストし、正しくレンダリングされ、期待どおりに動作することを確認できます。


次に、アプリケーションのユニットとコンポーネントが期待どおりに連携して動作するかどうかをテストする「統合テスト」があります。


最後に、実際のユーザーが使用しているかのようにアプリケーションをテストする「エンドツーエンド UI テスト」があります。 CI ワークフローでは、これは通常、シミュレーターまたはエミュレーターを使用して自動化され、アプリのさまざまな経路をテストし、コードに変更を加えた後に問題がないことを確認します。


ここで、私が冒頭で話した顧客は、アプリにログインできないためにエンドツーエンドの UI テストを実行できずに行き詰っていました。当時、彼らはログイン部分をバイパスした「開発」バージョンをテストしていました。


しかし、 「パトロール」が利用できるようになったため、その必要はなくなりました。

入場してステージ左、パトロール!

ではまずパトロールとは何でしょうか?まあ、ドキュメントが最もよく言っていると思います:


Patrol は、LeanCode によって開発された Flutter 用の新しいオープンソース UI テスト フレームワークです。 Flutter の既存のテスト ツールの上に構築されており、以前は不可能だったことが可能になります。パトロールを使用すると、Flutter アプリが実行されているプラットフォームのネイティブ機能にアクセスできます。


ここで最も重要な部分は、 Flutterアプリが実行されているプラットフォームのネイティブ機能にアクセスできることです。


これは、次のようなことができるようになることを意味します。


  1. 許可リクエストダイアログを操作して、リクエストを却下または受け入れます。
  2. WebView と対話します。
  3. アプリを最小化および最大化します。
  4. Google 認証や Apple 認証などの認証フローと対話します。
  5. 通知トレイを開く、ホームボタンを押す、Wi-Fi 接続のオン/オフ、デバイスのダーク モードへの変更など、他のネイティブ機能と対話します。


なるほど、これは素晴らしいと思いますが、問題は何でしょうか?


まあ、それはありません!さらに、無料であるだけでなく、オープンソース


さらに、Patrol には、テストを作成するためのより簡潔な構文を提供する「カスタム ファインダー」も導入されています。それらについて詳しく読むことができますここ

Patrol のインストールと設定

Patrol を開始するには、CLI をインストールし、 Pubspec.yamlPatrol 依存関係を追加し、iOS および Android プロジェクトでいくつかの構成をセットアップする必要があります。


LeanCode はいくつかの優れたドキュメントを作成しましたここここで各プラットフォームのプロセスを確認できます。ステップバイステップのガイドでは、 iOSAndroidの両方のセットアップについて説明します。


何か問題が発生した場合は、参加できるパトロール コミュニティ Discordサーバーに助けを求めるのが最適です。ここ


バグを見つけた場合は問題を提起できますここ

Patrol のインストールと設定

Patrol を開始するには、CLI をインストールし、 Pubspec.yamlPatrol 依存関係を追加し、iOS および Android プロジェクトでいくつかの構成をセットアップする必要があります。


LeanCode はいくつかの優れたドキュメントを作成しましたここここで各プラットフォームのプロセスを確認できます。ステップバイステップのガイドでは、 iOSAndroidの両方のセットアップについて説明します。


何か問題が発生した場合は、参加できるパトロール コミュニティ Discordサーバーに助けを求めるのが最適です。ここ


バグを見つけた場合は問題を提起できますここ

Patrol を使用してネイティブ機能テストを作成する

これですべてのセットアップが完了したので、いくつかのネイティブ機能のテストを開始しましょう。自分で試すために、クリックするとネイティブのアラート ダイアログが開く、高いボタンを備えたシンプルな Flutter アプリをセットアップしました。


「OK」または「キャンセル」をクリックすると、ダイアログが閉じます。


ネイティブ機能を備えたアプリをテストする


繰り返しますが、Patrol 独自のドキュメントを使用することをお勧めします。ここ最初のテスト ファイルを追加します。


そこで、テストとして、「Click me!」というテキストが表示された上部のボタンをクリックしてみました。これは標準の Flutter ウィジェットなので、次のパトロール ファインダーを使用してタップできます。


 await $('Click me!').tap();


ネイティブ ダイアログが表示されるので、ネイティブ UI コンポーネントとの対話を開始できるようになります。そこで、「OK」ボタンをタップできるようにするネイティブ ファインダーを追加しましょう。


 await $('Click me!').tap(); await $.native.tap(Selector(text: 'OK'));


それは簡単でした! 「キャンセル」ボタンもテストしたいので、「クリックしてください!」ボタンをタップしてみましょう。ボタンを再度クリックし、次のようにさらに数行を追加して、ネイティブ ダイアログの [キャンセル] ボタンをタップします。


 await $('Click me!').tap(); await $.native.tap(Selector(text: 'OK')); await $('Click me!').tap(); await $.native.tap(Selector(text: 'Cancel'));


完成したテスト ファイルは次のようになります。


 import 'package:cmpatrol/main.dart'; import 'package:patrol/patrol.dart'; void main() { patrolTest( 'Native tests', nativeAutomation: true, ($) async { await $.pumpWidgetAndSettle(const MyApp()); await $('Click me!').tap(); await $.native.tap(Selector(text: 'OK')); await $('Click me!').tap(); await $.native.tap(Selector(text: 'Cancel')); await $('Click me!').tap(); await $.native.tap(Selector(text: 'NO')); }, ); }


これで、テストを起動するコマンドを使用して、エミュレータまたは実際のデバイスでそのテストを実行できるようになります。私の統合テスト ファイルは「button_test」という名前だったので、次のようにターミナルからテストを開始しました。


 patrol test -t integration_test/button_test.dart


テストが成功したか失敗したかをターミナルで直接確認できます。テストが失敗した場合は、完全なテスト レポートへのリンクが表示されます。あるいは、私のように Android でテストを実行している場合は、次のディレクトリのindex.htmlをクリックしてレポートにアクセスできます。


 ./build/app/reports/androidTest/connected 


Gradle インデックス.html


通知トレイを開く、Wi-Fi を無効にする、ダーク モードを有効にする、アプリの最小化と最大化など、他のネイティブ機能をさらに試すことができます。


 // minimize app await $.native.pressHome(); await $.native.openNotifications(); await $.native.disableWifi(); await $.native.enableDarkMode(); // maximize app await $.native.openApp();


⚠️ アプリを完全に閉じてから再度開くことはできないことに注意してください。そうするとテスト全体が終了し、テストが失敗するためです。


パトロールに相談してくださいドキュメンテーション他の例については。

Codemagic ワークフローでの Patrol の使用

Patrol をワークフローに組み込むには、まずビルド マシンにPatrol CLIをインストールする必要があります。これには数秒しかかかりません。それが完了すると、テスト スクリプトを実行できます。以下は、これらの手順をcodemagic.yaml構成ファイルの「scripts」セクションに追加する方法の例です。最初のスクリプト ステップの 1 つとして、Patrol CLI をインストールするスクリプトを実行することをお勧めします。その後、その直後、または事前に実行したい他のテストの後に、Patrol テストを実行できます。


パトロール テストを実行する前にエミュレータを起動する必要があるため、エミュレータを起動するスクリプトを追加し、エミュレータが完全に起動するまで待ちます。 Apple Virtualization Framework はネストされた仮想化をサポートしていないため、Apple Silicon M1 または M2 マシンを使用するマシンでは Android エミュレータを利用できないことに注意してください。したがって、Android アプリをテストするときは、 Linuxインスタンスを使用することをお勧めします。


codemagic.yamlの script セクションは次のようになります。


 scripts: ... - name: Install Patrol CLI script: dart pub global activate patrol_cli - name: Launch Android emulator script: | cd $ANDROID_HOME/tools emulator -avd emulator & adb wait-for-device - name: Run tests with Patrol script: patrol test -t integration_test/your_test.dart ignore_failure: true ...


Codemagic ビルド ログに Patrol テスト結果を表示する

Patrol テストの結果はJUnit XML形式でも入手できます。つまり、Codemagic ビルド概要画面のビルド ログに表示できます。生成される JUnit XML ファイルへのパスにtest_reportプロパティ パスを追加するだけです。ブール値を指定してignore_failureプロパティを使用すると、ワークフローの残りの部分を実行し続けるかどうかを制御できます。次のセクションで説明するように結果をテスト管理システムにアップロードする場合は、これをtrueに設定する必要があります。


スクリプトがどのようになるかの例を次に示します。


 scripts: ... - name: Run tests with Patrol script: | patrol test -t integration_test/your_test.dart test_report: build/app/outputs/androidTest-results/connected/*.xml ignore_failure: true ...


失敗したテストは次のようになります。


Codemagic ビルド ログの JUnit XML テスト結果の失敗

Patrol テスト レポートをビルド アーティファクトとして収集する

さらに実行したいことの 1 つは、エラーが発生した場合に完全なレポートを表示できるように、テスト レポート出力をビルド アーティファクトとして収集することです。これを行うと、左側の「アーティファクト」セクションのビルド概要画面でレポートを zip ファイルとしてダウンロードできるようになります。これを行う最も簡単な方法は、レポート ファイルが存在するディレクトリを、Codemagic がアーティファクトのエクスポートに使用するディレクトリにコピーすることです。このディレクトリを参照する$CM_EXPORT_DIRという組み込み環境変数があり、スクリプトで使用できます。


これを行うスクリプトは次のようになります。


 scripts: ... - name: Export Patrol test report script: | cp -r build/app/reports/androidTests/connected $CM_EXPORT_DIR/report ...


結論

Patrol は、ネイティブ機能を伴う UI および統合テストの実行の問題をついに克服しました。ネイティブ機能をテストし、認証フローやネイティブ ダイアログを操作したり、Wi-Fi、セルラー、ダーク モードなどのネイティブ機能を切り替えたり、アプリの最小化と最大化を行うこともできるようになりました。さらに、これは無料かつオープンソースであり、Flutter の発売以来存在している実際の問題に対する解決策を提供します。さらに、Codemagic ワークフローに簡単に追加して使用できます。 LeanCode の素晴らしい取り組みをサポートしたい場合は、pub.dev で Patrol に「いいね!」を押してください。ここPatrol GitHub リポジトリにスターを付けますここ




この記事は、次のソリューション エンジニアリング責任者である Kevin Suhajda によって書かれています。コードマジック。ケビンは次のサイトで見つけることができますバツ GitHub 、 そしてリンクトイン


ここでも公開されています。