#はじめに
最近、AirtestIDE でスマホアプリ(ゲーム)のテスト自動化をはじめました。そこで実際に作成したスクリプトや環境をつくるために実施したことを綴ってみたいとおもいます
#環境
macOS 10.13.6
Airtest IDE 1.2.2(Python)
Android 9
#スクリプト
###共通で使うスクリプトを取り込む
from airtest.core.api import using
using("common.air")
from common import *
どうやればいいのかなやんでいたら、公式ドキュメントに書いてあったという
https://airtest.readthedocs.io/en/latest/README_MORE.html#import-from-other-air
###処理を待つための処理
import sys
def waitForExists(obj, timeout = 60):
for t in range(timeout):
if (exists(obj)): return 1
elif t == timeout - 1:
print("timeout")
sys.exit()
sleep(1)
objを見つけるまで処理を待ちます
まだ、timeoutの例外処理までつくりきれていない
raise WaitForObjectTimeoutError("処理がタイムアウトしました")
こんな感じにしたい
def waitAndTouch(obj, timeout = 60):
for t in range(timeout):
if (exists(obj)):
sleep(1)
touch(obj)
return 1
elif t == timeout - 1:
print("timeout")
sys.exit()
sleep(1)
objをみつけるまで待って、みつけたらタップします
def swipeForExists(obj, obj2, vector, dulation = 8, maxCount = 10):
for c in range(maxCount):
if (exists(obj)): break
elif c == maxCount - 1:
print("maxCount")
sys.exit()
elif (exists(obj2)):
swipe(obj2, vector, duration = dulation)
objをみつけるまでobj2をスワイプします
def tapForExists(obj, obj2, timeout = 60):
for t in range(timeout):
if (exists(obj)):
sleep(1)
touch(obj)
return 1
elif t == timeout - 1:
print("timeout")
sys.exit()
elif (exists(obj2)): touch(obj2)
sleep(1)
objがみつかるまでobj2をタップし続けます(objがみつかったらタップします)
def tapForNotExists(obj, obj2, timeout = 60):
for t in range(timeout):
sleep(1)
if (not exists(obj)): return 1
elif t == timeout - 1:
print("timeout")
sys.exit()
elif (exists(obj2)): touch(obj2)
objがみつからなくなるまでobj2をタップし続けます
def tapForNotExistsXY(obj, x, y, timeout = 60):
for t in range(timeout):
sleep(1)
if (not exists(obj)): return 1
elif t == timeout -1:
print("timeout")
sys.exit()
else:
touch(v=(x,y))
objがみつからなくなるまで特定の座標をタップし続けます
def tapIfExists(*args):
n = 0
for i in args:
n += 1
if (exists(args[0])):
sleep(1)
if (n == 1):
touch(args[0])
elif (n == 2):
touch(args[1])
引数が1つの場合:対象のobjがあったらタップします
引数が2つの場合:対象のobjがあったら、obj2をタップします
このぐらいつくると、大抵のやりたいことは事足りるようになってきました
###ログを出力する
import datetime
def log_ok(file, msg):
now = datetime.datetime.now()
#for airtestIDE
file.write(now.strftime("%Y/%m/%d %H:%M:%S") + " [info] " + msg + " OK" + chr(10))
#for airtest
#file.write(now.strftime("%Y/%m/%d %H:%M:%S") + " [info] " + msg.decode("utf-8") + " OK".decode("utf-8") + chr(10))
file.flush()
AirtestIDEと、Airtest で文字コードの処理が異なる模様
import codecs
file = codecs.open("<ログファイル名>", "w", "utf-8")
log_ok(file, "自動テスト開始")
###for IDE
install("../<アプリ>.apk")
###for CLI
#install("<アプリ>.apk")
log_ok(file, "Step1 - インストール")
start_app("<アプリのid>")
#(略)
log_ok(file, "自動テスト終了")
stop_app("<アプリのid>")
file.close()
使用例。なお、アプリのパスが、IDEから実行する場合と、CLIから実行する場合で若干異なる模様
IDE・・実行したairフォルダがホームになる
CLI・・実行した場所がホームになる
###結果をSlackに投稿する
import json
import requests
url = "https://slack.com/api/chat.postMessage"
token = "<token>"
channel = "<channel>"
message = "ログ出力の" + chr(10) + "サンプルです"
body = {
'token' : token,
'channel' : channel,
'text' : message,
'as_user' : 'true'
}
requests.post(url, data=body)
出力したログファイルをとりこんで、Slackに投稿しようとおもっている
https://api.slack.com/methods/chat.postMessage
#コマンドライン
###コマンドラインから実行する
adb shell input keyevent KEYCODE_WAKEUP
cd $PROJECT_HOME
/Applications/AirtestIDE.app/Contents/MacOS/AirtestIDE runner "<プロジェクト>.air" --device Android:/// --log log
Jenkinsとかからシェルを叩いてもらって起動するイメージ
###レポートを取得する
/Applications/AirtestIDE.app/Contents/MacOS/AirtestIDE reporter "<プロジェクト>.air" --log_root log --export exp
airtestよりも、AirtestIDEの方がリッチなレポートが取得できる
レポートの出力先を apacheの DocumentRoot に設定して、イントラネットから参照できるようにするとよさそう
###複数台つないで実行する
$ airtest run argo.air --device Android://127.0.0.1:5037/<serialno>
複数台のスマホ端末をUSBで接続している場合、adb devices
コマンドでリストされる<serialno>
を指定すれば、同時に複数台の実行ができそう(まだ AirtestIDEで試していない)
#おわりに
参考になった箇所などありましたでしょうか。実際にスクリプトを実装してみようとしたときに躓くポイントがいくつかありましたので、何かのお役に立てたなら幸いです