FlutterアプリでのMagicPodを使ったE2Eテスト実例

# はじめに

現在、弊社ではWeb/モバイル共にMagicPodを導入しE2Eテストの拡充を図っています。

MagicPodとはAIテスト自動化クラウドサービスで、Web/モバイル共にノーコードまたはローコードでテストシナリオを作成できます。

https://magicpod.com/

色々と試行錯誤している段階ですが、自分がMagicPodでできるFlutterアプリの自動テストの具体的内容やちょっとした知見をこの記事を通して共有したいと思います。

# 対象読者

* Flutter(に限らず)モバイルアプリでのE2Eに興味がある人
* MagicPodが気になっている人

# 書かないこと

* 他テスト手法との使い分けのような比較
* 他E2Eツールの比較観点

まだ試行錯誤中のため。。。 :pray: 

# 前提情報

弊社では医療向けの国家試験対策アプリを展開しており、いくつかのアプリはFlutter製になってる段階です。

一番注力しているアプリが以下の歯科衛生士アプリで

https://apps.apple.com/jp/app/%E6%AD%AF%E7%A7%91%E8%A1%9B%E7%94%9F%E5%A3%AB-%E5%9B%BD%E5%AE%B6%E8%A9%A6%E9%A8%93-%E5%B0%B1%E8%81%B7%E6%83%85%E5%A0%B1-%E3%82%B0%E3%83%83%E3%83%94%E3%83%BC/id1159639638

https://play.google.com/store/apps/details?id=ac.kakomon.android.dh&hl=ja&gl=US

開発環境ベースでまずはMagicPodのE2Eテストの導入を進めました。
これから記載していくテストケースは、MagicPodのトライアル期間を通じて作ったものになります。

# 自分が組んだテストケースの形

自分は基本的に以下のことができているテストケースを作っていきました。

* クラウド環境でいくつかの自動テストが回ること
* 複数の機能を使ったシナリオテストベースでのテストケース

歯科衛生士以外の職種アプリもあり1つだけならまだ確認は大丈夫ですが、複数アプリ✖️2OS分を手動テストで確認するのは非常に大変です。
将来的にある程度は複数アプリのテストを同じテストケースを使って自動化したいと考えてます。

上記2点を元にアプリの以下機能で

* 認証機能
    * ログイン
    * 新規会員登録〜退会処理(も含む 一度作ったアカウントを削除して、次テスト時に利用できるようにするため)

でまずはテストケースを作成しました。該当するアプリ画面は以下になります。

**ログイン** 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/485cc080-2c3b-1f65-e8dc-ff0573d7daf1.png" width="200">

**新規会員登録**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/bc2c9520-57c1-26fb-f224-62627f331ac0.png" width="200">

MagicPodのモバイルのテスト実行環境として3パターンあり、`クラウド`を選ぶとMagicPod側で用意しているクラウド環境で実行できます。

![スクリーンショット 2023-12-14 0.35.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/b5df864a-90c8-39d5-5a87-b6e8dc0a3432.png)

iOSの場合はSimulator

![スクリーンショット 2023-12-14 22.10.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/aebdf080-3fb1-7144-0026-cf38c5665a4e.png)

AndroidはEmulator
![スクリーンショット 2023-12-14 22.12.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/193cf344-6b4d-bb20-54c9-252cca310f6f.png)

で実行します。

OSバージョンなどの具体的なサポート環境はこちらで確認できます。

https://support.magic-pod.com/hc/ja/articles/4408827432089-%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E7%92%B0%E5%A2%83

# テストケース作成に関して

[ヘルプ自体](https://support.magic-pod.com/hc/ja/articles/7556329570457-%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%82%AC%E3%82%A4%E3%83%89-2-%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E5%89%8D%E5%8D%8A-%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%97%E3%83%AA-)も非常に充実していますが、実際のアプリでどういう風にテストケースを作成していくか簡単に説明します。

## 流れ

1. テストケースを作成し、編集画面に遷移
2. 実行する端末のセットアップ
3. 実際に動かしながらテストを作っていく

### 1. テストケースを作成し、編集画面に遷移

コンソール画面より`テストケースを追加` > 各フォームに入力するとテストケースの画面に遷移します。

![スクリーンショット 2023-12-14 22.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/d05ba2ad-c7bd-3140-97a5-df2c9621ee9a.png)

`テストケースを編集`を押すと具体的にテストを作っていく画面に遷移します。

![スクリーンショット 2023-12-14 22.34.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/d4c2a05b-8008-0b79-d381-ad387c58120b.png)

:::note info
本来はアプリファイルをアップロードしてからでないと、右の端末内に何も表示されませんがいくつか共有ステップを作成しているため出てきています。共有ステップが何かに関しては後述します。
:::

### 2. 実行する端末のセットアップ

SimulatorまたはEmulatorのセットアップを矢印の箇所から設定することができます。
![スクリーンショット 2023-12-14 23.30.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/3e582082-49c9-931b-5b11-d086411fc205.png)

ボタンを押すとウィンドウが表示され、OSの箇所を変更すると実行するSimulatorまたはEmulatorの設定を選ぶことができ、
![スクリーンショット 2023-12-14 23.32.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/2149e643-a8af-bd39-b75d-470d392d5dfc.png)
![スクリーンショット 2023-12-14 23.36.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/5c000ffa-ebcd-b20e-a9ad-1053401dbb43.png)

iOSはappファイル,Androidはapkファイルをアップロードして起動ボタンを押すとSimulatorまたはEmulatorにアプリをインストールすることができます。

appファイルの作成方法は[MagicPodのヘルプ](https://support.magic-pod.com/hc/ja/articles/4408836787609?_gl=1%2Ar4ee8o%2A_ga%2ANjY4NzY5NDQ5LjE3MDE3NDU0ODI.%2A_ga_4W0MHF6GXK%2AMTcwMjU1OTIyNC4xOS4xLjE3MDI1NjA3MzEuNjAuMC4w%2A_gcl_aw%2AR0NMLjE3MDIwMjc3MzcuQ2p3S0NBaUFtc3VyQmhCdkVpd0E2ZS1XUE5TdUF3WldKLTRhRVI1bFI4TDlOS0hsVmxrNnNyZFo0X3ZPY2NCQVlQcHlCOVVSclFOLVFCb0NlUllRQXZEX0J3RQ..%2A_gcl_au%2AOTIwNTkxMDIzLjE3MDE3NDU0ODE.)で詳細がわかります。

### 3. 実際に動かしながらテストを作っていく

MagicPodは具体的な画面内の要素を検出しながらテストを作成していきます。

UIを検出するための`要素選択`という機能があり、これを使ってUIの検証や操作などの実行の流れを用意していきます。

![スクリーンショット 2023-12-14 23.49.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/c5f712dc-850c-1da2-2019-994ca3fdff33.png)

下記の内容はオンボーディング画面でテストケースを作っていく例です。
最後のオンボーディング画像まで行くと`スキップ`という文言が非表示になるかチェックするテストを作っていきます。↓

![画面収録-2023-12-14-23.55.52.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/1a348c92-4b5f-363a-9bf4-b30937e4e857.gif)

UIの検出が終わったら、端末内の特定のUIを選択すると1行ごと(MagicPodでは`ステップ`という)に追加されます 。
上記のgifの例ですと次へボタンを選択し、ステップが追加されます。

ステップが追加されると何を実行するかという`コマンド`が入り、ボタンの場合だとデフォルトでタップというものが入ります。別のコマンドに変更すること自体も可能です。そして、そのコマンドを実行すると端末内の画面が操作されます。

これを繰り返して、最終的に期待する結果になるかというテストケースを作っていくことができます。

![画面収録-2023-12-15-0.23.37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/61379217-7ea7-e75a-a5d5-f6d1bb3fb467.gif)

MagicPodには`確認`というアサーションのコマンドがあり、最後のオンボーディング画像までいくと `スキップ`という文字が非表示になるかというチェックを入れてます。

このような流れでテストケースを作っていくことができます。

また、実行する際に画面の変更のたびにキャプチャも自動で撮ってくれます。

![スクリーンショット 2023-12-15 0.32.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/ce6e31f7-1368-f259-0f39-ae85efaf3458.png)

画面を前の状態に戻して再度各ステップを編集しなおす、、、とかは特に必要なく撮ったキャプチャをベースにコマンドへの追加も可能です。

![スクリーンショット 2023-12-15 0.34.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/62f65e74-9389-1723-dcb1-4c8bb110d743.png)

どういうコマンドがあるの？と気になった方は、コマンドに関しても以下ヘルプページより確認できます。↓
[コマンド一覧](https://support.magic-pod.com/hc/ja/articles/4409927190425-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E4%B8%80%E8%A6%A7)

## 最終的にどういうものを作った？

### 上記で挙げたログインと新規会員登録のテストケース

ログインのテストケースはログイン処理の失敗時と成功時にどうなるかのテストケースを作成

![スクリーンショット 2023-12-15 1.08.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/b04f310b-3201-7466-6948-d396e4f14704.png)

新規会員登録に関しては、弊アプリの会員登録の形式が対話型形式のためフォームごとにあるバリデーションエラーや入力が有効になると次のフォームへ・・・という一連の流れを実行し最後に会員登録処理を行えるかをチェック、また作ったアカウントを退会処理まで行うというものを作りました。

対話型の会員登録のため、だいぶステップ数が長くなりました。。。。↓

![スクリーンショット 2023-12-15 1.11.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/b288d0a3-46d0-dd6a-52db-0dfbeb007fab.png)

![スクリーンショット 2023-12-15 1.11.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/0cd24ea0-8118-83bc-a9ed-c064b7e4a5a3.png)

#### 共有ステップについて

また、個人的に便利と思う機能で `共有ステップ`という機能があります。

共通処理をまとめた関数のようなもので、他のテストケースでも同じステップを毎回用意することなく使い回すことができます。

![スクリーンショット 2023-12-15 1.16.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/0dbc2b26-a062-92c8-7a74-4e19e837053a.png)

テストの初回実行時(新規インストールとして実行される)にプッシュ通知のパーミッションダイアログが出て、許可もしくは許可しないを押さないと画面が固まってしまいます。

各テストケースごとに通知のパーミッションダイアログが出ても対処できるように、共有ステップとして用意すると非常に便利でした。また、テストケースのステップ数も減って見やすくなる利点もありました。

具体的な共有ステップの作り方はヘルプより↓

[共有ステップの活用](https://support.magic-pod.com/hc/ja/articles/4408910141977-%E5%85%B1%E6%9C%89%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%E3%81%AE%E6%B4%BB%E7%94%A8)

### スケジュールベースでの自動テスト一括実行からSlackへ送信

また各テストケースの定期的な一括実行とSlackへのテスト結果送信も試しました。

スケジュールでの一括実行も曜日ごとや特定の時間で設定できます。

![スクリーンショット 2023-12-15 1.34.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/4f179aa5-50ad-1d4e-3734-511b8dad16c4.png)

![スクリーンショット 2023-12-15 10.54.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/d0c7c730-2e28-4204-8447-118ab95f3c82.png)

特定のSlackチャンネルへの結果の送信形式ですが

![スクリーンショット 2023-12-15 1.39.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/8bf5ce66-ba6a-1663-cd6e-830e660f2392.png)

![スクリーンショット 2023-12-15 1.39.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/1941f278-33e3-804b-6630-09ed90309c9f.png)

失敗時は失敗したテストケースと、そのエラーを表示してくれてわかりやすい仕組みになっています。

[連携の仕方](https://support.magic-pod.com/hc/ja/articles/6259603606553-%E3%83%86%E3%82%B9%E3%83%88%E7%B5%90%E6%9E%9C%E3%82%92%E9%80%9A%E7%9F%A5%E3%81%99%E3%82%8B#h_01G3X8JP09EJ6QQ9SA1GZDFY6T)

# 良かったところや個人的な所感

上記で説明しながら挙げた共有ステップやSlackへのテスト結果の通知も良かったですが、他の自分が個人的にMagicPodのいいなと思う点をまとめます。

## 実際のテストコードっぽくテストケースを作成できる

![スクリーンショット 2023-12-14 0.56.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/2906e63f-c177-fa85-602e-501877fe21d8.png)

ステップにはコメントや改行のステップもあります。実際のテストコードを書くようにコメント入れたり、改行入れたりして可読性や意図を残せるのは便利でした。

チームで運用する際はコーディング規約を作って、メンテしやすいようにするといったこともできるかなと思いました。(やりすぎかもだけど)

## OSのUIの箇所が対応しやすい

FlutterのテストだとIntegration Testも同様にE2Eテストできますが、OS側のUIを操作するのが難しいです。E2Eツールならではのメリットですが、プッシュ通知のパーミッションダイアログもOSのUIのためそういう箇所の対処がしやすいです。

:::note info
一応、最近あったFLutterKaigi2023の[テスト戦略見直しのセッション](https://speakerdeck.com/ostk0069/flutter-apuriniokerutesutozhan-lue-nojian-zhi-sitozi-dong-tesutonodao-ru?slide=78)で[patrol](https://pub.dev/packages/patrol)を使えば解決できると発表がありました。

自分がMagicPodでテストケース組んだ時は全く知らなかった。。。
:::

## バージョン管理の仕組みがある

テストケースにバージョン管理(`履歴`)の仕組みもあります。

矢印箇所のボタンから保存でき
![スクリーンショット 2023-12-15 11.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/241f90e5-7797-138e-eaac-a7dbad5f061b.png)

変更したテストケースとしてタイトルと詳細を入力して、どういう変更をしたかというものを残すことができます。

またそのバージョンごとの変更差分も確認でき、前のバージョンに戻したいといったようなこともできていいと思いました。(単純に待機時間を変更した例)↓
![スクリーンショット 2023-12-15 11.23.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/076c783a-db9a-cb76-829e-b8639bc88741.png)

## 問い合わせの仕組みが便利

問い合わせの仕組みも非常に便利だと感じました。

右の`テスト失敗の理由を問い合わせる`からそのまま問い合わせができます。
![スクリーンショット 2023-12-15 11.52.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/09aca6e8-2a64-621c-87b3-a7aca7ad0325.png)


例えば、想定と違う挙動していて確認したい場合にテスト失敗時のどういう環境で〜ログが〜〜期待する結果と実際の結果が異なって〜〜という詳細かつ正確な情報を送らないとやり取りが往復して大変になります。

![スクリーンショット 2023-12-15 11.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80912/5fe41740-4a75-0ca7-af39-7f9b3d630daf.png)

ですが必要なテストケースやAppiumのログやキャプチャなどそのまま送信することができ、お互いにやり取りしやすいような仕組みはとてもいいなと思いました。

# 今後やっていきたいこと

まだ解像度高く分析はできてませんが、MagicPodでテストケースを作成していく内にE2Eに向いているものいないものがテスト自動化していくうちに個人的に分かってくるようになりました。

まだまだ以下のことができてなく↓

* 他のシナリオテストの拡充
    * 例 アプリの機能としてある 好きな問題を解くための条件を設定 → 問題画面に遷移し過去問を解く
* Bitriseとの連携
* ビジュアルテスト
* テストの最適化

特にCI/CDツールは元々Bitriseを導入しているので、MagicPodとの連携してテストフローの一部に組み込む連携周りを強化していきたいです。