游戏测试 自建 GAutomator 的框架 使用解读 (一)

陈子昂 · October 01, 2019 · Last by 陈子昂 replied at October 01, 2019 · 734 hits

十一节有时间,看完阅兵后正好写文章。

使用前注意

属于腾讯开源平台,安卓的话不低于API18,python版本支持2.7,3.4+以上版本,3.7不确定是否支持,3.6可用。
支持引擎:unity,虚幻4
支持不是魔改版本的NGUI和UGUI。如果不是这2类Ui插件的,可以在GAutomatorView,就是类似appium Inspector,用于定位UInode元素和提供查询。
GAutomatorView和github上 clone的项目不要放在中文目录下。
同样也是嵌入式的,游戏界面修改频繁,但是gameObject和gameResource变动频率并不高,使用嵌入式和ORC配合,可以在场景选择方面更灵活,自动化代码稳定性更高。

使用描述

GA是属于打包了python类库进去,属于一个工程项目,毕竟一些公司因为内网权限问题,从外网导入python类库源码编译安装并不方便。GA的理念就是clone项目后,在MD文件内就图片和tables说明了项目结构。
PS:如果在这个基础上进行二次开发和增加前置和后处理的,需要去自己治理本地文件目录和新扩展的怎么放,一些函数形式的API功能文件进行导入覆盖重写,这个是后话。
上述说明地址
sample是各接口使用例子。
wpyscripts 里面是GA的核心逻辑,链接内图片会红线说明,和它平级的有一个文件manager.py

manager.py

跳转 manager.py
主要是单例模式的实例化和获取devices和engine
如果自研框架需要做前置开发,让链接更稳定和异常判断出现问题进行重新实例化获取devices和engine就需要依赖这个文件

from wpyscripts.wetest.device import *  #line:18 导入后对获取devices
from wpyscripts.wetest.engine import * #engine UnityEngine没直接关系 导入后对获取engine
import wpyscripts.common.adb_process as adb #adb工具类
#os.environ.get(xxxx)和环境变量和本地配置挂钩.
#需要修改可以存到字典 manage_config ={"env": os.environ.get("PLATFORM_IP"),"hostip ":"省略"}
env = os.environ.get("PLATFORM_IP") #主要用来分岔行为,env 如果不为None,则是在云平台上使用。
hostip = os.environ.get("PLATFORM_IP", "127.0.0.1")
platform_port = os.environ.get("PLATFORM_PORT")
#line 67
if env:
get_device.instance = CloudDevice(serial, pkgname, launch_activity, ui_device)
else:
get_device.instance = NativeDevice(serial, ui_device)
#CloudDevice 暂时不考虑,看导入的区域,根据名字推断应该在 line18
#NativeDevice 我们看看本地创建的

python函数都是有返回的,没有返回就是None,所以在做一些判断条件时,不用和其他语言一样还需要特别添加布尔。

device.py/NativeDevice

跳转 device.py

#adb模式
get_device.instance = NativeDevice(serial, ui_device) # manager.py line70
get_device.instance = None #一个全局这句话很巧妙,也可以用到__init__.py里面
#serial和常规一样是获取adb.这个可以特殊编译过打包在项目工程内
#line 77
def _platform_forward(remote_port): #这个函数其实可以根据上面的env会返回什么来写个装饰器,如果本地运行调错了就会抛出信息
"""
在wetest平台运行时,forward映射的端口交由平台分配并且实现映射
:param remote_port:
:return:
"""

platform_client = platform.get_platform_client()
response = platform_client.platform_forward(remote_port)
return response["localPort"]

def get_engine(engine_type=EngineType, port=None)#line 88 获取引擎对象单例
#这个函数内,有env分岔
if env:
result = _platform_forward(int(unity_sdk_port))
local_port = result
else:
local_engine_port = os.environ.get("LOCAL_ENGINE_PORT", "53001") # 本地模式时与engine forward的端口号
res = forward(local_engine_port, unity_sdk_port)
logger.info(res)
local_port = int(local_engine_port)

#引擎名称分岔
ui_device = uiauto.get_uiautomator()
print("打印当前引擎信息:{}".format(ui_device))
if engine_type == "unity":
get_engine.instance = UnityEngine(hostip, local_port,ui_device)
elif engine_type == "ue4":
get_engine.instance=UnRealEngine(hostip,local_port,ui_device)
else:
raise ValueError("No {0} engine type".format(engine_type))

serial要单独讲下,如果里面不止一套的双框架模式(GA/airtest,GA/Ui2),这个adb环境变量地址有可能会和其他框架冲突,所以可以在连接时把adb地址打印出来。
开始检查 跳转 uiautomator_manager.py
核心是from libs.uiauto.uiautomator import AutomatorDevice

def get_reporter():   #line 118  属于wetest云平台,如果在其他函数内有使用到get_reporter 也说明和wetest云平台有关。
def save_sdk_version(version): #这个也是属于wetest云平台的。
"""
收集现有版本使用情况,可以针对性的去除你不想被我们收集的数据。
:param version: SDK版本
:return:
"""

如果自己自建了openstf和收集数据可以解析上面那段代码。

wetest/device.py

跳转 device.py

class DisplaySize(object): #line 35 屏幕显示,GA可以对屏幕自适应,看看这段信息
"""
Mobile Screen resolution
Attributes:
width: width px
height:height px
"""

#常规用法 长宽的px和类似一个toString()__str__

class TopActivity(object): #line 58 应该只是一个获取Activity信息的实体属性类
#省略代码
def exception_call_super(fn):
@wraps(fn)
def wrap_function(*args, **kwargs):
try:
return fn(*args, **kwargs)
except (WeTestRuntimeError, ConnectionException):
logger.warning("call cloud function {0} error".format(fn.__name__))
return getattr(super(CloudDevice, args[0]), fn.__name__)(*args[1:], **kwargs)
#CloudDevice看到有这个,而且在except 区域内说明是非本地的

class Device(object): #line 96 基础base
@retry_if_fail()
def get_rotation(self):#屏幕旋转 这个暂时不知道什么作用,因为游戏sdk可以设置是否反转和方向。

@retry_if_fail()
def get_display_size(self): #line 130 获取当前屏幕显示分辨率

@retry_if_fail()
def get_top_package_activity(self): #line 157 获取活动的窗体,注释using可以作为日常使用。

while line:
match = pattern.search(line) #这里加打印 match
if match:
top_activity = TopActivity(match.group(2), match.group(1)) #match.group(0)是全部,按顺序看。
return top_activity
line = result.readline()
return TopActivity("", self.ui_device.info["currentPackageName"])
#剩余的都是些功能函数

Minitouch.py

跳转 Minitouch.py

import six #做23python兼容
import atexit #这个很重要 按堆栈顺序来按顺序解除注册服务。

Mini连接器的类上面有一块的全局变量区域
里面有端口映射等,下面是minitouch工具类,因为主要是讲自建,先一笔带过,需要对文件夹和文件进行治理,就需要对工程内的最小单位到类和变量区域分别代表什么,进行了解。
下个文章研究wpyscripts/wetest文件夹下面其他文件。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 1 条回复 时间 点赞

🎁 👑 国庆节快乐。

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up