之前分享的 UI 自动化测试框架: 基于 ATX-Server 的 UI 自动化测试框架 实现了多设备的并行测试,能够自动生成报告并日志输出到指定的文件夹下面.
在此基之上,增加了基于 maxim 的压测功能.多设备的并行执行都是基于之前的基础之上.
能够实现 app 卸载重新安装之后,账号登录,进入到指定页面之后再执行 monkey 压力测试
GitHub 地址还是这个:https://github.com/pengchenglin/ATX-Test
在用 maxim 的时候,发现在在启动 uiautomator2 的时候,maxim 就没法用了,原因是 uiautomator2 和 Maxim 工作时都需要连接系统的 AccessibilityService.
在看 uiautomator2 的文档的时候发现是可以启停 android-uiautomator-server
d.service("uiautomator").stop() # 暂停
d.service("uiautomator").start() # 启动
atx-agent 提供执行设备端 shell 命令的功能,操作 maxim 其实用 shell 就够了.
push 相关的 jar 和配置文件到手机上;pull 运行完成后的 log 日志内容
WiFi 无线拉起执行 APP 稳定性 / 压力测试,免 USB 连线
基于 Android Monkey 二次开发,实现高速点击的 Android Monkey 自动化工具 fastmonkey - 代号 Maxim
浅谈自动化测试工具 python-uiautomator2
ATX_Test/Public/Maxim
文件夹下存放了 maxim 运行是需要的所有文件,运行的时候会将指定文件 push 到 Android 设备中.
ATX_Test/Public/maxin_monkey.py
是对 maxim 的 shell 命令的封装和执行 monkey 操作的两个方法封装,具体的参数定义在里面写比较清楚,可以直接去看代码
maxin_monkey.py 下 run_monkey 的代码如下
def run_monkey(cls, monkey_shell, actions=False, widget_black=False):
'''
清理旧的配置文件并运行monkey,等待运行时间后pull log文件到电脑
:param monkey_shell: shell命令 uiautomatortroy 时 max.xpath.selector文件需要配置正确
:param actions: 特殊事件序列 max.xpath.actions文件需要配置正确
:param widget_black: 黑控件 黑区域屏蔽 max.widget.black文件需要配置正确
:return:
'''
log.i('MONKEY_SHELL:%s' % monkey_shell)
cls.clear_env()
cls.push_jar()
if monkey_shell.find('awl.strings') != -1:
cls.push_white_list()
if monkey_shell.find('uiautomatortroy') != -1:
cls.push_selector()
if actions:
cls.push_actions()
if widget_black:
cls.push_widget_black()
cls.set_AdbIME()
runtime = monkey_shell.split('running-minutes ')[1].split(' ')[0]
log.i('starting run monkey')
log.i('It will be take about %s minutes,please be patient ...........................' % runtime)
# restore uiautomator server
cls.d.service('uiautomator').stop()
time.sleep(2)
cls.d.shell(monkey_shell)
time.sleep(int(runtime) * 60 + 30)
log.i('Maxim monkey run end>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
# restore uiautomator server
cls.d.service('uiautomator').start()
然后就是在ATX_Test/Public/Driver.py
下增加了run_maxim
实现 maxim 的多设备执行操作
ATX_Test/Monkey
下是登录操作的脚本和最终的运行 maxim_monkey 的执行文件,运行就执行 monkey_run.py 就好了
ATX_Test/Monkey/monkey_run.py 的代码:
from Public.Drivers import Drivers
from Public.Report import *
from Public.maxim_monkey import Maxim
import unittest
from Monkey import login_steps
if __name__ == '__main__':
# back up old report dir 备份旧的测试报告文件夹到TestReport_backup下
data = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
backup_report('./MaximReport', './MaximReport_History', data)
cases = unittest.TestSuite()
cases.addTest(login_steps.abcd('test_install_login'))
command = Maxim().command(package='com.github.android_app_bootstrap', runtime=1, mode='uiautomatordfs',throttle=500,options=' -v -v ', whitelist=True)
Drivers().run_maxim(cases=cases, command=command, actions=True, widget_black=False)
还是使用了 macaca 的 bootstrap app 作为 demo 演示
执行 monkey 前 卸载重装,账号登录的操作直接写成了 unitest 的脚本,这样原来的 UI 自动化写的脚本直接拿来用,其实很简单的几行就搞定了
class abcd(unittest.TestCase, BasePage):
@classmethod
@setupclass
def setUpClass(cls):
cls.d.app_stop_all()
@testcase
def test_install_login(self):
'''安装启动android_app_bootstrap'''
self.d.app_uninstall(pkg_name)
self.local_install(apk_path)
self.d.app_start(pkg_name)
self.set_fastinput_ime()
time.sleep(3)
login.login_page().input_username('username')
login.login_page().input_password('password')
login.login_page().click_login_btn()
运行 maxim 的命令通过 maxim_monkey.py 下的 Maxim().command 来实现组装
最后执行 Public.Drivers().run_maxim 来开始运行
运行 maxim 的主要代码如下:
def _run_maxim(run, cases, command, actions, widget_black):
log = Log()
log.set_logger(run.get_device()['model'], os.path.join(run.get_path(), 'client.log'))
log.i('udid: %s', run.get_device()['udid'])
# set cls.path, it must be call before operate on any page
path = ReportPath()
path.set_path(run.get_path())
# set cls.driver, it must be call before operate on any page
base_page = BasePage()
if 'ip' in run.get_device():
base_page.set_driver(run.get_device()['ip'])
else:
base_page.set_driver(run.get_device()['serial'])
try:
# run cases
base_page.d.shell('logcat -c') # 清空logcat
if cases:
run.run_cases(cases)
Maxim().run_monkey(monkey_shell=command,actions=actions, widget_black=widget_black)
base_page.d.shell('logcat -d > /sdcard/logcat.log')
time.sleep(1)
base_page.d.pull('/sdcard/logcat.log', os.path.join(path.get_path(), 'logcat.log'))
base_page.d.pull('/sdcard/monkeyerr.txt', os.path.join(path.get_path(), 'monkeyerr.txt'))
base_page.d.pull('/sdcard/monkeyout.txt', os.path.join(path.get_path(), 'monkeyout.txt'))
base_page.set_original_ime()
base_page.identify()
except AssertionError as e:
log.e('AssertionError, %s', e)
设定好报告存放的路径,初始化设备之后,执行相关的操作:
1.清空 logcat
2.存在 UI 自动化操作 cases 的执行 cases
3.开始运行 monkey(push 相关的文件到手机,执行 monkey shell 命令)
4.monkey 执行完成,将logcat.log
monkeyerr.txt
monkeyout.txt
push 到电脑上报告存放的路径
在 monkey_run.py 同级目录下,会将结果存在于一时间命名的文件夹下,不同的设备存在在不同的设备文件夹下