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

#はじめに
最近、AirtestIDE でスマホアプリ（ゲーム）のテスト自動化をはじめました。そこで実際に作成したスクリプトや環境をつくるために実施したことを綴ってみたいとおもいます
#環境
macOS 10.13.6
Airtest IDE 1.2.2（Python）
Android 9
#スクリプト
###共通で使うスクリプトを取り込む
```python
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

###処理を待つための処理
```python
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("処理がタイムアウトしました")```
こんな感じにしたい

```python

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をみつけるまで待って、みつけたらタップします

```python
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をスワイプします

```python
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がみつかったらタップします）

```python
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をタップし続けます

```python
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がみつからなくなるまで特定の座標をタップし続けます

```python
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])
```
引数が１つの場合：対象のobjがあったらタップします
引数が２つの場合：対象のobjがあったら、obj2をタップします

このぐらいつくると、大抵のやりたいことは事足りるようになってきました

###ログを出力する
```python
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 で文字コードの処理が異なる模様

```python
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に投稿する
```python

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

#コマンドライン
###コマンドラインから実行する
```sh
adb shell input keyevent KEYCODE_WAKEUP
cd $PROJECT_HOME
/Applications/AirtestIDE.app/Contents/MacOS/AirtestIDE runner "<プロジェクト>.air" --device Android:/// --log log
```
Jenkinsとかからシェルを叩いてもらって起動するイメージ

###レポートを取得する
```sh
/Applications/AirtestIDE.app/Contents/MacOS/AirtestIDE reporter "<プロジェクト>.air" --log_root log --export exp
```
airtestよりも、AirtestIDEの方がリッチなレポートが取得できる
レポートの出力先を apacheの DocumentRoot に設定して、イントラネットから参照できるようにするとよさそう

###複数台つないで実行する
```shell
$ airtest run argo.air --device Android://127.0.0.1:5037/<serialno>
```
複数台のスマホ端末をUSBで接続している場合、```adb devices```コマンドでリストされる```<serialno>```を指定すれば、同時に複数台の実行ができそう（まだ AirtestIDEで試していない）

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