该项目实现播放次数和播放时长的数据上报进行自动化校验,解决发版手工校验播放器数据上报以及北极星埋点的痛点,保障数据的正常上报和落表。
Airtest官方文档
AirtestIDE下载地址
Python <= 3.9
已把所有依赖项整理成了requirement.txt文件,详情可见项目(用pycharm打开可选择自动下载所有依赖)
使用苹果账号或苹果开发者账号,登录Xcode,并注册真机设备
选择 Team -> Add an Account -> 登录苹果账号(个人免费或开发者账号)
选择 TARGETS -> WebDriverAgentRunner -> Build Settings -> Basic
双击 Product Bundle Identifier值,填写一个属于自己独一无二的字串
回到,上文提过的Signing & Capabilities界面,查看有无报错
无报错,则继续;若有报错,查看 登陆开发者账号
1.4 启动Test,在菜单栏 product -> Test。当你看到这样的日志的时候,代表 iOS-Tagent 已经启动成功了
一点坑,xcode 12.x报错Building for iOS Simulator, but the linked and embedded framework ‘***‘ was built …解决方式,将Validate Workspace为Yes后,重新编译
运行报错: wda.exceptions.WDAUnknownError: WDARequestError(status=110, value={‘error’: ‘unknown error’, ‘message’: ‘-[XCUIScreen screenshotDataForQuality:rect:error:]: unrecognized selector sent to instance 0x2832349c0’})
Airtest是网易开源的一款UI自动化测试项目,基于python脚本的方式,用于web、windows程序、app自动化测试.
官方文档介绍:airtest官网
在每个测试用例执行之前都会先进行初始化配置:
具体分为三步:
核心函数:buryingpoint_setmockrule_new()
该函数用于设置 Mock Rule,以在自动化测试中对每个case模拟指定的response或者request。以下是对函数的详细说明:
该函数使用了 Python 的 requests 模块来发送 HTTP 请求,post请求地址如下:
通过控制两次post请求传参来改变 hasson平台上mock规则的状态(开关):
代理规则配置json文件:
每个case具体配哪个mock规则在conf.py文件中配置:
核心函数:buryingpoint_cleanup_new()
该函数用于清理 mock log 数据,以准备下一次的自动化测试。以下是对函数的详细说明:
该函数实现清理hasson平台上指定env、host、path 下的日志数据,实现初始化,便于后续读取每个case的日志上报。
通过遍历conf.py文件的入参字典中的数据构建 args 列表,其中包含了需要清理的 Mock Log 的相关信息。
随后函数会调用 delete_mock_log 函数来发送http请求以删除 Mock Log。
核心函数:start_log_collection(cls)
该函数实现手机日志的清理,开启一个子线程开启手机日志清理任务
随后创建一个AndroidLogThread对象log_thread,用于在后台收集并保存设备的日志信息。
以下为开启日志线程的具体实现(安卓端为例):
埋点上报自动化在UI定位和操作上结合了airtest框架和poco框架
pages文件夹涵盖了目前case所需的所有UI控件名以及坐标位置
部分代码示例:
相关控件属性可以通过airtest IDE 提供的 poco-inspecter 抓取。
相关的操作函数都经过封装放在了keywords文件夹下
结合了poco框架和airtest框架提供的部分函数,以及一些shell指令实现。
部分代码示例:
相关的case实现放在了testcase文件夹下,通过对封装好的操作函数进行拼接就可以实现各种case的UI操作
核心函数:buryingpoint_player_assert()
该函数用于对api接口上报数据和es数据库中的数据的预期值和实际值进行断言。
函数会检索conf.py文件下的配置信息,获得对应case的预期值字典(包含api和es的校验预期值)
随后函数会获取api接口实际上报的值和es库中的值,和预期值进行比对。
vv:
vt:
vv包含的所有字端vt均需要校验
当前会校验上报的数量和接口的数据
核心函数: get_actual_api_counts_and_values()
该函数用于获取实际的API计数和值
mock_env:模拟环境信息
check_point:检查点信息
actual_api_counts:实际API计数字典
actual_api_values:实际API值字典
该函数会检索conf.py文件,并获取到对应case 的mock_env, host, path作为入参
然后去调用get_mock_log_info函数去通过post请求获取hasson平台上的mock_log日志
最后对返回的json数据进行整理,过滤,获得实际的上报的值
核心函数: get_es_data()
该函数用于从Elasticsearch获取ESP数据。它接受日志ID、Buvid、起始时间戳等参数作为输入。
构建Elasticsearch查询的URL、请求头和排序方式,以及根据输入参数构建查询字符串,包括环境、日志ID、Buvid、事件ID等
获取当前时间戳 lte 并构建Elasticsearch查询的查询体,发送POST请求到Elasticsearch,获取返回结果。
解析返回结果,提取命中的文档列表和文档数量。
遍历每个命中的文档:
billions-proxy 支持通过Restful api的方式查询ops-log/uat-log中的数据
uat-log使用姿势
http需要包含的header
统一访问地址:172.22.33.113:81/{location}
Appid: billions Appkey: proxy
相应的请求方法对应location为:
v7/
v7/
请求body必须传入!!!
日志查询接口:
curl --location --request POST 'http://172.22.33.113:81/v7/billions-datacenter.buryingpoint.buryingpoint-@*/_search' \
--header 'content-type: application/json' \
--header 'Appid: billions' \
--header 'Appkey: proxy' \
--data-raw '{"size": 2, "sort": {"@timestamp": {"order": "asc"}}, "query": {"bool": {"filter": [{"query_string": {"query": "fields.env:\"prod\" AND \"logId=000032\" AND \"buvid=ZB485FB68E7385DB42BA887F688058916AF5\""}}, {"range": {"@timestamp": {"gte": 1647513614961, "lte": 1647513645514}}}]}}}'
(gte:开始测试的时间,lte:当前的时间)
核心函数:get_play_time_v2()
该函数用于从手机日志文件中获取ijk播放器状态和事件来计算播放器以及小窗的播放时间、暂停时间、倍速播放时间。
逐行读取日志文件,并从每行中提取ijk播放器相关信息,将其存储在 player_record 列表和 small_player_record 列表中。
接着遍历 player_record 列表,根据时间戳和播放器状态计算播放时间和暂停时间。
处理特定事件,例如播放速度更改或在播放过程中切换项目。
计算完播放时间和暂停时间后,将结果存储在 time_list 列表中。
该函数还会计算小窗口播放器(miniplayer)的持续时间(如果适用)。
过滤手机日志中获取小窗相关的事件以及里面的mCTime去计算小窗的持续时间,开始时间
过滤出来的日志如下:
已支持从fawkes平台上自动下载包以及包的安装和卸载
通过对指定接口发送get请求获取到自己当下构建好的包,从接口返回中拿到下载的url
然后把这个链接下载到本地项目中,再通过调用shell指令去安装指定的apk
此处注意把params、cookies、headers 改成自己实际的值,否则无法请求到自己构建的包
已支持企业微信机器人,后续接入测试报告的推送。
本项目是在UAT环境下基于Hasson和数据平台进行校验,UI脚本与数据校验相分离
在conftest.py文件下面设置设备的参数:
示例:
相关conf.py 配置如下:
确保设备正确连接:请确保您的设备已连接到计算机,并且在执行测试之前已完成设备驱动程序的安装和设置。可以通过运行 adb devices 命令来验证设备是否正确连接。
重启设备和计算机:有时候,重新启动设备和计算机可以解决连接问题。尝试断开设备,并重新启动设备和计算机,然后再次进行测试。
检查设备调试模式和USB调试选项:确保设备已启用调试模式,并且 USB 调试选项已启用。这些选项通常在设备的开发者选项中找到。启用调试模式后,重新连接设备并尝试运行测试。
检查设备连接方式:根据您的测试环境,可能需要使用正确的连接方式。例如,如果您正在使用真实的 Android 设备,则需要使用 Android:/// 进行连接。如果您正在使用模拟器,则可能需要使用相应的模拟器连接方式。
更新相关软件:确保您使用的相关软件(如 Airtest、ADB)是最新版本,并且与您当前的测试环境兼容。有时候,更新软件可以解决一些已知的问题或错误。
这个错误提示表明你的ADB(Android Debug Bridge)客户端版本与ADB服务器版本不兼容。ADB客户端和服务器之间需要保持相同的版本以确保它们可以正常通信。
要解决这个问题,你可以尝试以下几种方法:
更新ADB客户端:如果你的ADB客户端版本较旧,请尝试更新到与ADB服务器版本匹配的最新版本。你可以从Android SDK Manager中下载最新的ADB版本,或者从Android官方网站上下载ADB二进制文件并手动替换掉旧版本。
降级ADB服务器:如果你的ADB客户端是最新版本,但服务器版本过高,可能需要将ADB服务器降级到与客户端兼容的版本。你可以在Android SDK目录下找到ADB二进制文件,并替换为与你的ADB客户端版本匹配的较旧版本。
检查环境变量和路径设置
把pycharm中的adb版本改成和终端下载的版本一致即可
把这个路径 /venv/lib/python3.9/site-packages/airtest/core/android/static/adb/Mac/adb 下的adb 换成终端下载好的adb就行
获取es的接口对网段做了一些限制
每条case都会实例化多个poco对象,若手机后台自动清理了poco,框架自带的监控进程会不断尝试重启,影响自动化运行
修改框架里面的Androiduiautomation类变成了单例模式实现,全局只实例化一个对象(目前的做法)
或者参考一下下面的文章,修改一下手机的设置项:
poco无限重启解决办法
由于跟播放时长和暂停时长的计算逻辑是根据ijk播放器的状态去计算,并未结合ijk播放器的事件去计算,受网络原因影响或者手机性能影响会造成计算值与实际值不准确的情况(自动化时间算法和开发那边的逻辑不一致),可能有类似于缓冲态这种事件,会导致计算不准确。
airtest框架问题,长时间运行代码可能某些case截取屏幕就会失败,所以建议某些case最好不使用airetest框架,直接用adb shell来控制手机的操作
直接去请求get 平台的信息,平台做了一些过滤,只会给出接口上报的请求体,响应头和响应体信息。
若后续需要增加的字段是在请求头中的,比如 buvid , 需要修改请求的参数,并把这个字段做处理增加到校验列表里(已在代码中实现)
已新增mock规则,每个case结束 history接口上报的progress = -1 ,即不记录历史记录
后续只需要在conf.py中 在对应的case 配置一下这个mock规则即可。