首先感谢网易的各位大神,从 ATX 到 Airtest 收获颇多

在手游中,一般新手指引都是固定的强制步骤,所以我们可以用自动点击的方式直接跑完整个新手

现行方案

以上三种方法,在编写测试代码的时候都需要手动跑至少一遍新手测试
坐标的话,需要测量计算
图片的话,主要的工作量在截图
UI 对象的话,只需要测需要的 UI 就可以了(可能并不需要手动跑完整个新手)
对比下来,UI 的工作量是最小的;而且以上三种方法可以结合使用
而且使用 UI 对象有个最大的优势,可以取到游戏内的文本,可以进行更复杂的逻辑操作

代码示例

学 ATX 时写的基于图片操作,完全写死的步骤

# -*- encoding: utf-8 -*-

import atx
from atx.ext.report import Report # report lib
import time

game_name = u"xxx"  隐藏了
device_name = u"84B7N16620000490"
package_name = u"xxxxx" 隐藏了
activity_name = u"xxxxx"    隐藏了
pic_url = u"C:\\Users\\HBoPRC\\xxx\\"

d = atx.connect(device_name)
rp = Report(d, save_dir = pic_url + "Report\\")
rp.patch_uiautomator() # for android UI test record (optional)
rp.info(u"Test started")
d.click_image(pic_url + 'queding@auto.png')
time.sleep(2)
......省略
#关闭队伍界面
d.click_image(pic_url + 'zy_180@auto.png', offset = (1, -0.5), safe = False)
time.sleep(2)
#一段对话
d.click(0.5, 0.5)
time.sleep(3)
#点击前往挑战
d.click_image(pic_url + 'zy_0@auto.png', offset = (-1.5, -1), safe = False)
time.sleep(5)
#停止指引
d.click(0.5, 0.5)
rp.close()

这段代码中,详细列举了新手的每一步操作,搜索图片,然后点击对应的位置
因为代码中所写的步骤都是固定的,所以面临两个问题

所以我们需要一个更好的办法来解决通用和中断的问题

部分资料
Python 基础:http://www.runoob.com/python3/python3-tutorial.html
Poco 文档:http://poco.readthedocs.io/zh_CN/latest/
Poco 示例:http://poco.readthedocs.io/zh_CN/latest/source/README.html#tutorials-and-examples

修改过程

接下来的过程以另一个游戏为例,使用基于 UI 的方式来执行新手指引的过程

这里需要提前集成 Poco-SDK

我们先分析下整个新手过程中的通用部分,我们主要是把整个新手拆分成不同的 UI,方便我们进行不同的操作

有了大致的 UI 后,我们可以考虑直接使用循环点击指引手指指引的位置,过程中存在其它界面时,就执行对应的操作,大致结构如下:

while(true):
    if 指引手指.exists():
        点击手指位置
    elif 剧情对话.exists():
        点击剧情对话
    elif 其他界面.exists():
        点击界面位置

上面的代码就不需要和最初那样,考虑新手指引的步骤;因为一直在检查当前界面显示的 UI,所以也不用考虑执行中断后重哪里继续
但是游戏过程中需要考虑到一个问题,在网络中断的时候,弹框会和指引手指或者其它界面一起出现;虽然其它 UI 会被提示框遮挡,但是 UI 还是存在于当前界面的;所以在判断的时候,需要考虑下编写的顺序

优化过程

在 Poco 的示例中有一个等待 UI 出现的方法

https://poco-chinese.readthedocs.io/zh_CN/latest/source/poco.pocofw.html#poco.pocofw.Poco.wait_for_any

在超时前返回等到的第一个 UI 代理对象,等不到 UI 时会报错
所以上面的代码可以改一下:

while(true):
    ui = poco.wait_for_any([指引手指,剧情对话,其他界面])
    if ui is 指引手指:
        点击手指位置
    elif ui is 剧情对话:
        点击剧情对话
    elif ui is 其他界面:
        点击界面位置

但是在等待过程中,一直没有找到 UI 时,会报错,我们可以在报错的时候做一些处理,比如停止循环

while(true):
    try:
        ui = poco.wait_for_any([指引手指,剧情对话,其他界面])
    except:
        break
    if ui is 指引手指:
        点击手指位置
    elif ui is 剧情对话:
        点击剧情对话
    elif ui is 其他界面:
        点击界面位置

最终代码

最终使用 Poco 跑新手流程的完整代码

# -*- encoding=utf8 -*-
__author__ = "HBoPRC"

from airtest.core.api import *
from poco.drivers.unity3d import UnityPoco
# 连接设备
connect_device("Android:///")
# 初始化poco
poco = UnityPoco()
# 定义一个变量来判断是否还在新手阶段
isGuide = True
while (isGuide):
    # 每次需要重新获取各个界面,以保证取到最新的信息
    # 剧情对话界面
    talkV = poco("剧情对话")
    # loading界面,这里主要是进出战斗耗时比较长,单独列出来
    loadW = poco("loading")
    # 创建界面
    roleS = poco("角色创建")
    # 指引手指
    finger = poco("指引手指")
    # 获得奖励界面,因为有战斗,结算界面没有手指,需要单独处理
    getA = poco("奖励界面")
    # 各类提示框,主要是断线那部分弹框
    popWin = poco("提示框")

    try:
        # 等待出现上面的界面,设置120s超时,默认就是120s,可以按实际情况修改
        # 这里写UI参数的时候需要注意下先后顺序,因为常见的情况:指引的时候可能会断线重连,弹出提示框,此时会同时存在指引手指和提示框,需要先处理提示框
        guideV = poco.wait_for_any([popWin, talkV, loadW, roleS, country, getA, finger], timeout = 120)
    except:
        # 没找到上面的界面,设置不在新手阶段,跳出循环
        isGuide = False
        break
    # 判断,根据出现的界面进行相关的操作
    if guideV is popWin:
        # 因为提示框的层级最高,我们需要优先判断处理,因为主要是考虑的断线重连情况,这里可以加一个休眠,保证跳过连接过程;或者是再单独判断一个转圈的UI
    elif guideV is talkV:
        # 如果是对话框,点击关闭
    elif guideV is loadW:
        # 这里单独处理loading是因为考虑到进入副本战斗的时候,loading过了,还需要先战斗一段时间才会进行指引提示;其实也可以把wait方法里的超时设长点
    elif guideV is roleS:
        # 角色创建界面,进行选择头像,性别,姓名之类的操作
    elif (guideV is getA):
        # 这里关闭掉结算奖励界面
    elif guideV is finger:
        # 指引手指,点击对应的位置就行了

完成以上步骤后,我们已经可以运行一个完整的新手流程了
接下来可以使用命令直接运行写好的 .air 脚本

http://airtest.readthedocs.io/zh_CN/latest/README_MORE.html#run-test-case

将命令保存为不同的批处理文件后,批量打开,就可以做到最简单的多台机器同时运行了,需要注意,如果使用命令的话,需要将脚本内连接设备的代码删掉

python -m airtest run xinshou.air --device Android://127.0.0.1:5037/手机序列号 --log \log\nexus4
python -m airtest report xinshou.air --log_root \log\nexus4  --outfile \log\nexus4\log.html --lang zh
pause


↙↙↙阅读原文可查看相关链接,并与作者交流