この記事は Akatsuki Advent Calendar 2018 の25日目の記事です。
前回はZepprixさんの開発環境インフラを ECS 移行している話でした。
この記事について
AirtestというUIテストツールを使ってテストを自動化しようという話です。
プロジェクトに導入したくて、どのように利用できるのかを調べたのでそのまとめになります。
経緯
スマホアプリ開発では運営が続くにつれて機能が増えていくため、検証コストが増加していくという問題があります。
そのため、基本的な機能の動作確認(チュートリアルなど)を可能であれば自動で行えるようにしたいと思ったのがきっかけです。(あと自分の興味)
Airtestとは
AirtestはNetEaseが開発しているゲーム向けの画像認識によるUIテストツールです。
AndroidとWindowsに対応しています。(iOSはベータ版)
Airtestを使う
導入
今回はAirtestIDEを利用します。
リンク先からダウンロードしてインストールまで行なってください。
また、ADBが使える環境とAndroid端末を用意してください。
今回はMaths ChallengeというUnityの完成プロジェクトをサンプルとしてテストを作成します。
まずは、上記のプロジェクトをビルドしてAndroid端末にインストールしてください。
その後、AirtestIDEを起動すると右上にMobile Phone Connection
というウィンドウがありAndroid端末を接続しているとその情報が表示されます。(接続しているけど表示されない場合はrefresh ADB
をクリック)
接続が正しくできている場合はAction
にconnect
と表示されそこをクリックするとAndroidの画面が表示されるようになります。
テストを作成する
早速テストを作っていきましょう。
UIが表示されているか・されていないかのテストを作成します。
AirtestIDEの左にあるAirtest Assistant
ウィンドウにあるassert_exists
をクリックし
Device Screen
に表示されている画面でMATHS
と表示されている領域を選択します。
上記のコードがScript Editor
に書かれたと思います。
これでMATHS
が表示されているのかをチェックできます。
試しに実行してみましょう。
Run Script
で実行してLog viewer
にOK
と出ていたらテスト成功です。
あとはこのタイトル画面の仕様に沿ってUIテストを作成していきます。
画像がないのでわかりにくいですが、自分は以下のようなテストを作成しました。
# -*- encoding=utf8 -*-¥
from airtest.core.api import *
# アプリをインストール
install("/Users/~/Downloads/Maths Challenge/sampleBuild.apk")
# アプリ起動
start_app("com.MadFireOn.MathsChallenge")
# 起動待機
sleep(5.0)
# タイトル画面のUIチェック
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951184937.png, record_pos=(-0.001, -0.718), resolution=(1080, 1920)), "MATHSが表示されているか")
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951192539.png, record_pos=(-0.003, -0.498), resolution=(1080, 1920)), "CHALLENGEが表示されているか")
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951205702.png, record_pos=(-0.015, -0.013), resolution=(1080, 1920)), "PLAYボタンが表示されているか")
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951215401.png, record_pos=(-0.001, 0.309), resolution=(1080, 1920)), "QUITボタンが表示されているか")
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951294447.png, record_pos=(0.347, 0.732), resolution=(1080, 1920)), "設定ボタンが表示されているか")
# タイトル画面の初期状態ではオプションUIは表示されていないこと
assert_not_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951359799.png, record_pos=(-0.276, 0.732), resolution=(1080, 1920)), "Rateボタンが非表示になっているか")
assert_not_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951374244.png, record_pos=(-0.128, 0.738), resolution=(1080, 1920)), "Infoボタンが非表示になっているか")
assert_not_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951382645.png, record_pos=(0.026, 0.734), resolution=(1080, 1920)), "MoreGameボタンが非表示になっているか")
assert_not_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951395246.png, record_pos=(0.181, 0.73), resolution=(1080, 1920)), "Musicボタンが非表示になっているか")
# オプションUIの表示をチェック
touch(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951294447.png, record_pos=(0.347, 0.732), resolution=(1080, 1920)))
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951359799.png, record_pos=(-0.276, 0.732), resolution=(1080, 1920)), "Rateボタンが表示されているか")
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951374244.png, record_pos=(-0.128, 0.738), resolution=(1080, 1920)), "Infoボタンが表示されているか")
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951382645.png, record_pos=(0.026, 0.734), resolution=(1080, 1920)), "MoreGameボタンが表示されているか")
assert_exists(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951395246.png, record_pos=(0.181, 0.73), resolution=(1080, 1920)), "Musicボタンが表示されているか")
touch(Template(file:///Users/~/Maths Challenge/AirTestScript/Title.air/tpl1544951294447.png, record_pos=(0.347, 0.732), resolution=(1080, 1920)))
# ホーム画面へ戻る
home()
# アプリをアンインストール
uninstall("com.MadFireOn.MathsChallenge")
CLIで実行する
実際にプロジェクトでテストを実行する場合はIDEで実行するよりもCLIから実行できた方が他サービスとの連携が楽です。
CLIで実行する場合はAirtestIDEのAndroidとの接続を切ってください。(接続したままCLIから実行するとエラーが発生します)
また、MACとLINUXでCLIから実行する場合はパーミッションの変更が必要になります。
# for mac
cd {your_python_path}/site-packages/airtest/core/android/static/adb/mac
# for linux
# cd {your_python_path}/site-packages/airtest/core/android/static/adb/linux
chmod +x adb
CLIで以下のコマンドを実行するとテストが開始されます(Pathは各自の環境に合わせて置き換えてください)
airtest run "/Users/~/Maths Challenge/AirTestScript/Title.air" --device Android:///
--device
は接続するデバイスを指定します。
--device Android:///
だと接続しているAndroid端末になります。
ログを出力しレポートを作成する
CLIで実行する際に--log
オプションをつけるとログを出力してくれます。(AirtestIDEの場合はRun -> View Report)
Pathを指定しない場合は実行するスクリプトのディレクトリ内にログが出力されます。
また、airtest report
コマンドで、出力されたログファイルからHTML形式のレポートを作成できます。
airtest report "/Users/~/Maths Challenge/AirTestScript/Title.air"
出力されたレポートの中身は以下のようになっており、各テストごとに結果が表示されています。
テスト内容を録画する
CLIで実行する際に--record
オプションをつけるとテスト実行中に録画をしてくれます。
--log
オプションも指定しないと動画は保存されないようなので、録画したい場合は--log --record
をつけて実行してください。
まとめ
Airtestを使って画像認識によるUIテストの自動化を試してみました。
画像認識によるUIのテストは何年か前に話題になりましたし、似たことができるツールとして魅力を感じました。
全てのUIテストを自動化するのは管理・維持のコストの面で現実的ではありませんが、人の手によって繰り返し行われるテストの一部を自動化するだけでも価値はあると思います。
参考サイト
https://airtest.readthedocs.io/en/latest/index.html
https://qiita.com/majimeneko/items/4e8d2bb9fee6a88a4921