LoginSignup
17
5

More than 3 years have passed since last update.

AirtestIDE でテスト自動化の環境をつくる(Tips)

Last updated at Posted at 2019-12-14

はじめに

最近、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で試していない)

おわりに

参考になった箇所などありましたでしょうか。実際にスクリプトを実装してみようとしたときに躓くポイントがいくつかありましたので、何かのお役に立てたなら幸いです

17
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
5