【#PowerApps】キャンバスアプリもアプリなんだから自動テストを導入しよう

# 概要

Power Apps ある程度の規模のアプリを作成していくとテストが大変です。（そもそもそんな規模のアプリを作るなとかは今回の話とはそれるのでそれはそれ）小規模や２，３画面程度のアプリや更新がそれほど多くないアプリであれば手でテストしてしまったほうが早かったり楽なことも多いです。
しかし、業務に重要なアプリだったり、更新が頻繁に発生する可能性のあるアプリの場合、デグレや不具合を減らすためにもテストの重要度は上がってきます。


# テストスタジオ

Power Apps のキャンバスアプリをテストする場合はテストスタジオを利用します。
以下公式からの引用です。
> Power Apps のテスト スタジオは、キャンバス アプリのテストを書き込み、整理、および自動化するための、わずかなコードを使用するソリューションです。 テスト スタジオでは、Power Apps の式を使用してテストを書き込んだり、またはレコーダーを使用してアプリの対話を保存し、式を自動的に生成したりすることができます。 書き込まれたテストをテスト スタジオで再生してアプリの機能を検証することができ、および Web ブラウザーでテストを実行して、アプリの展開プロセスに自動化されたテストを作成することもできます。
https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/test-studio#overview

## テストスタジオ用語集

### スイート（テストスイート）
テストケースをグループ化するために使用します。
テストケースが増えてくるとすべてのテストケースを実行するのに時間がかかったりします。また、一部の機能を修正したときにその機能の部分だけテストを行いたい時などに利用します。基本的には機能（例えば承認とか）ごとにまとめると良いと思います。
また、スイートに含まれるテストケースは上から順に実行されます。また、ケースが終了した時点で次のケースはその続きから開始されるため、スクリーン２に移動した場合次のテストはスクリーン２から開始されます。
スイートが開始された時点でアプリは初期スクリーンから開始しますが、スイート内でテストケースは再度読み込みが開始しない点にご注意ください。

### ケース（テストケース）

ケースはステップとアクションで構成されています。
テストステップは Power Apps の式を利用して書かれます。
テスト内容を書く場所になります。


## 制限事項

現時点(2020/12/08時点)で以下のことはテストできません。

- コンポーネントのテスト
- PCF を利用したコンポーネントのテスト
- 入れ子になったギャラリーを対象としたテスト
- メディアコントロール

など



# やり方

今回はテンプレートアプリの携帯レイアウトから Asset Checkout のテンプレートを利用してテストしていきましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/e8471348-9127-85ab-ba23-fa9558d1f049.png)


まずは作成→保存のあとテストスタジオを起動します。
もし以下の警告が表示された場合は実験的な機能の数式レベルのエラー管理をONにしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/f0e46d5c-7510-7fcf-0bc5-9ada53af599a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/5f43b1a3-c2de-99ad-8188-0408aed8eb06.png)

テストスタジオ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/4ac629bf-6098-1f77-9a5a-aa3a0e71abcd.png)

## スイートを作成する
今回は Laptops の Review を確認するテストを書いてみましょう。
とはいえ、最初は式を記載するわけではなく、Power Automate Desktop のように操作を記録していきます。

テストスタジオの録音(Record)を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/eba3fa39-79f3-b01d-0e0b-e2c725737e19.png)

するとアプリが立ち上がり、記録する画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/e870bc7d-c5f5-96c1-f935-8224159934a5.png)

LAPTOPS → Notebook の (1review) → Review 詳細の順に選択していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/c09739cb-17b7-8104-6b8a-ed1130bd2659.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/ea04e1fe-1d45-dca9-57cb-49ef0a376f87.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/e6ba5576-7bfe-e960-db33-588bde0b6f64.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/891edbaa-69e9-c9c9-0233-a163dec6d06f.png)


ここまで来たら「完了」を選択して記録を終了しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/a5e179fb-9011-7790-4e12-bc28c22a75c6.png)

すると全部で 4ステップ記載されているのがわかります。
Record で作成したケースはすべて Power Apps の数式で記載されているのが確認できます。
そのため、Record 機能を使わずに自力で書いていくことも可能です。（コピペで対応したい場合など）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/5a7f8618-c264-b5f2-a89a-22f449221ba2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/721d7e7f-f6f4-d555-7213-3f004b894815.png)

今回は表示されているレビューが正しいことを確認したいので、ステップ5で確認(アサート)処理を行います。

ステップ4 を選択し、３点リーダーから下にステップ→Assertの順で選択しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/9e7d987f-e395-a555-3bb2-47521f68af70.png)

そして以下のようにアクションに式を記載します。

```
Assert(TextBox4_15.Text = "This is a major step up from my last laptop, bigger screen, more memory, and much faster.")
```

ここまで完了したら　保存 → 公開 → 再生の順で選択します。
モデル駆動型と同じように変更を加えたら公開を必ず行いましょう。
公開を行わない場合、最後に公開を行ったテストが実行されます。
正しく再生すると以下のようになります。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a><br>テストスタジオいいね。思った通りに動いた。 <a href="https://t.co/Myi0CefPEZ">pic.twitter.com/Myi0CefPEZ</a></p>&mdash; たく丸 (@taku_ma_ru) <a href="https://twitter.com/taku_ma_ru/status/1336276950944337922?ref_src=twsrc%5Etfw">December 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Assert で失敗した場合は式が間違っている可能性があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/7a6a62d9-549f-ba58-deb3-7e6e03d8297c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/5ac300d3-dfe8-1bb1-e5b6-390a567e2369.png)

## テストスタジオ以外でテストを実行する

**現時点(2020/12/8)ではテストが途中で止まったりと動作が不安定です。**
基本的にはテストスタジオでテストを実行すれば良いと思ってますが、中には Azure DevOps などを利用し継続的なビルドとリリースパイプラインにテストを統合したいこともあります。
そういった場合は再生リンクのコピーから URL をコピーし利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/45656df1-2de9-5890-de6b-98ab01d04ff2.png)

コピーしたURLはブラウザに張り付けて移動するとテストが開始されます。

## テストスイートを使いこなす

テストを進めていくことで、テスト開始時に何かを初期化したり、開始時に変数に対して値を設定するといったことを行いたくなってきます。
そういった機能もテストスイートは持っています。

### OnTestCaseStart
テストケースが開始されるときに実行されます。

### OnTestCaseComplete
テストケースが完了したときに実行されます。

### OnTestSuiteComplete
テストスイートが完了したときに実行されます。

試しにテストケース開始時に Homeから開始する処理を書いてみましょう。
テストケース開始時なので、 OnTestCaseStart に記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/c85820b4-3f90-b3db-28c1-98e4fe6c395c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/5b788007-ff11-3d1e-226d-0d1e1e48c172.png)

```
Navigate(HomeScreen)
```

そして同じように Review を確認するテストケースを適当に追加します。

テストスイートを選択し、保存→公開→再生を行いましょう。
テストスイートの考えではテストケースごとに状態のリセットは行われないため、本来であれば失敗します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/dc7ea725-5021-8233-26ab-592a03c442e4.png)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a><br>なるほど。<br>各イベントはそのタイミングで発火するのね。<br>これは便利だなぁ<br>OnTestCaseStart<br>OnTestCaseComplete<br>OnTestSuiteComplete <a href="https://t.co/6FpJ8qvaIz">pic.twitter.com/6FpJ8qvaIz</a></p>&mdash; たく丸 (@taku_ma_ru) <a href="https://twitter.com/taku_ma_ru/status/1336283555245117440?ref_src=twsrc%5Etfw">December 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

また、こういったイベントを駆使することで、例えばテスト完了時に何件失敗して何件成功したといった情報をメールや Power Automate などに送信することが可能です。
今回はテスト完了時にPower Automate に情報を送信してみましょう。
まず、Power Automate を作成します。

トリガーは Power Apps を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/68450946-b8f4-cf1c-7cf0-f5f82d6754c3.png)

Power Apps 側に Power Automate の接続を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/0fc27c36-2d46-3461-d79a-c516cd661f37.png)


OnTestSuiteComplete に以下の式を追加します。

```
TestResultCheck.Run(JSON(TestSuiteResult))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/041de5ab-bd56-190b-21e7-f8ca254594e4.png)

ここまで完了したら保存→公開→再生しましょう。

スイートが完了すると以下のように Power Automate が実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/422bdc94-105a-484a-ccd8-22db38a4373a.png)


# まとめ

テストスタジオを利用した Power Apps キャンバスアプリの自動テストは直感的に利用できる機能です。アプリを作っていくことでこういったテストの自動化は避けては通れなくなってくる部分なのでぜひ利用できるようになりましょう。


## 注意点

以下現時点で確認している動作

- ギャラリーは初期選択時のみ２回選択が必要
- テスト中に実行中のタブを切り替えるとテストは停止か失敗する