背景

需要实现跑步性能测试,我们的实现流程是安卓开发单写了一个类似于小熊快跑的 app,这个 app 的唯一功能是解析 gps 文件,然后快速模拟定位,然后打开某 APP 跑步模块,就可以模拟跑步了,由于在 release 版本内关闭了模拟定位的功能,只在 debug 包内支持模拟定位跑步的功能。这样实现流程就简单了。

graph TD

安装模拟GPSAPP-->传入GPS文件

传入GPS文件-->启动APP跑步模块

启动APP跑步模块-->记录手机端的性能数据

记录手机端的性能数据-->分析报告

关键点

里面涉及到几个关键实现的点,我一一列举一下。

1、启动模拟跑步 APP 和 APP 跑步模块

很久之前,写过 Appium 的自动化测试,但是这次准备用 atx。

因为之前写 iOS UI 自动化的时候接触过 atx,atx 即封装的 webdriveragent,和 uiautomator。

pip install --upgrade --pre atx --user -U

pip install opencv_contrib_python --user -U

官方文档提供了一些简便的 api,由于我只当前只关注 Android,其实我对 iOS 更熟悉,因为之前在研究 python-wda 源码的时候也有过一点点的贡献。

话不多说,上代码。

首先,在安装好 atx 以后可以检查一下环境和当前的版本:

python -m atx version

# 检查环境配置是否正常

python -m atx doctor

还好,都是正常的。

这个时候,我从 Jenkins 构建拿到了两个 APP,分别是 APPDebug 版本和模拟跑步 APP。

先用 atx 支持的命令取得 app 的包名和启动 activity 名字

举其中 GPS.apk 的例子。

python -m atx apkparse GPS.apk {

"version": {

"code": "1",

"name": "1.0"

},

"main_activity": "com.FakeGPXActivity",

"package_name": "com.fakegps"

}

取到 packagename 和 activity 之后,就可以启动 app 然后进行一系列的操作了。

## 启动模拟 GPS数据app

import atx

self.driver = atx.connect()

self.driver.start_app("com.fakegps", "com.FakeGPXActivity")

2、获取手机端的内存和 PSS 值

对于如何获取手机端的性能数据,testerhome 里面有很多这方面知识的描述,我简单描述最后如何放在启动 APP 和执行点击操作的调用。

是通过异步的方式,先在启动 APP 前,初始化获取数据的线程,然后在执行操作的命令前,结束数据的获取。

因为在给 Flask 增加单元测试中,当时接触过 Python 的几个测试框架,对 Nose 最有好感,最后用例的编写是通过 Nose,启动,直接通过 nosetests 即可。

import atx

## 这里是封装的取Android性能数据的部分代码

from cpu_mem_log_thread import CpuMemLogThread

packagename = 'com.xx'

activity = 'com.xx'

packagename_gps = 'com.xxx'

activity_gps = 'com.xxx'

filename = 'perftest.log'

class test():

def setup(self):

self.driver = atx.connect()

self.driver.start_app(packagename_gps, activity_gps)

self.driver.sleep(5)

self.driver.start_app(packagename, activity)

self.log_thread = CpuMemLogThread(packagename, filename)

self.log_thread.start()

def teardown(self):

self.exit_run_module()

self.log_thread.stop = True

self.driver.stop_app(packagename)

self.driver.stop_app(packagename_gps)

def exit_run_module(self):

self.driver.click_exists(resourceId='running_button_change_mode_to_normal')

self.driver(resourceId='pause_button').long_click()

if self.driver(resourceId='finish_button').exists:

self.driver(resourceId='finish_button').click()

else:

raise Exception(u"出错了,没有结束按钮")

# print self.driver.dump_view()

self.driver(text=u'确定').click()

def test_run(self):

self.driver.sleep(5)

self.driver.click_exists(text=u'运动')

self.driver.sleep(2)

self.driver.click_exists(text=u'继续')

self.driver.sleep(5)

if self.driver(resourceId='running_button_change_mode_to_normal').exists:

self.driver.click_exists(resourceId='running_button_change_mode_to_normal')

else:

raise Exception(u"出错了,不在跑步地图界面")

# 这里我们默认让app模拟跑3个小时

self.driver.sleep(10800)

self.driver.screenshot('run_end.png')

nose 执行的时候会先调用执行 setup,在用例结束执行之后,会调用 teardown,所以把 setup 中放入了启动 APP 应用和开始执行性能数据抓取的动作,而在 teardown 中放入先停止执行性能数据抓取操作,最后 stop app 之前启动的 APP。

具体的执行命令是:

nosetests -v run.py --with-xunit

3、跑步性能测试的报告

单独配置了一个 html 模板,然后解析 nosetests.xml,加上截屏和 perf.log,作为数据参数。

然后通过 jinja2 传入 html 模板,然后生成报告,最后报告的样式如下:

后续

当我真正把这套流程部署在 Jenkins 上的 slave 以后,总是会出现,手机和 mac 连接不稳定的情况出现,当我都要放弃的时候,@codeskyblue提出已经升级了uiautomator2, 运行更加稳定同时也支持无线连接,也的确不在想重新配置 appium 环境,就用 uiautomator2 去解决 atx 稳定执行的问题

使用新的 uiautomator2 库

配置环境

git clone https://github.com/openatx/uiautomator2

cd uiautomator2

# 用当前用户权限安装

python setup.py install --user --prefix=

解压出 atx-agent 文件,然后打开控制台

$ adb push atx-agent /data/local/tmp

$ adb shell chmod 755 /data/local/tmp/atx-agent

# launch atx-agent in daemon mode

$ adb shell /data/local/tmp/atx-agent -d

这里的输出一定要是 0.0.3,再继续。若有问题,建议可以 adb shell 进去对 atx-agent 执行 chmod 授权操作。

由于我的手机 ip 和 mac 的网络不在同一个网段,因而需要一个 adb forward 转发操作,当然也可以直接启动手机端的 ip,不进行转发操作。

adb forward tcp:7912 tcp:7912

这个时候分别执行

adb shell 'echo $(curl -s localhost:7912/version)'

curl localhost:7912/version

显示0.0.3,说明环境已经配置好了,这个时候更新一下之前代码:

import uiautomator2

import time

from cpu_mem_log_thread import CpuMemLogThread

packagename = 'com.xx'

activity = 'com.xx'

packagename_gps = 'com.xxx'

activity_gps = 'com.xxx'

filename = 'perftest.log'

class test():

def setup(self):

self.driver = uiautomator2.connect('http://localhost:7912')

self.driver.app_start(packagename_gps, activity=activity_gps)

time.sleep(5)

self.driver.app_start(packagename, activity=activity)

self.log_thread = CpuMemLogThread(packagename, filename)

self.log_thread.start()

def teardown(self):

self.exit_run_module()

self.log_thread.stop = True

self.driver.app_stop(packagename)

self.driver.app_stop(packagename_gps)

def exit_run_module(self):

self.driver(resourceId='running_button_change_mode_to_normal').click()

self.driver(resourceId='pause_button').long_click()

if self.driver(resourceId='finish_button').exists:

self.driver(resourceId='finish_button').click()

else:

raise Exception(u"出错了,没有结束按钮")

# print self.driver.dump_view()

self.driver(text=u'确定').click()

def test_run(self):

time.sleep(5)

self.driver(text=u'运动').click()

self.driver(text=u'继续').click()

if self.driver(resourceId='running_button_change_mode_to_normal').exists:

self.driver(resourceId='running_button_change_mode_to_normal').click()

else:

raise Exception(u"出错了,不在跑步地图界面")

# 这里我们默认让app模拟跑3个小时

self.driver.sleep(10800)

self.driver.screenshot('run_end.png')

可以看到运行明显稳定太多,而且 api 基本也没有变化。

由于 uiautomator2 库并不完善,之前还不支持 activity 和 packagename 启动,我也提了一个特别简单的 pr,可以支持 activity 和 packagename 启动。

最后

感谢@codeskyblue,他的分享,让我们可以这么轻便的去实现简单的页面点击操作的需求。

一直在探索 UI 自动化实现性价比高的方式,因为我们都知道,UI 自动化投入产出比是不高的。

但是我们需要找到一些特别的方式,比如某个模块,而且人工真的不好经常重复操作的行为,感觉这才是 UI 自动化可以有突破的点。

Android adb模拟走步,某 APP 跑步模块性能测试相关推荐

  1. 某 APP 跑步模块性能测试

    背景 需要实现跑步性能测试,我们的实现流程是安卓开发单写了一个类似于小熊快跑的app,这个app的唯一功能是解析gps文件,然后快速模拟定位,然后打开某APP跑步模块,就可以模拟跑步了,由于在rele ...

  2. android+adb+push到系统下,Android adb push 应用到app/system

    Android adb push 应用到app/system 准备工作 具体操作 准备工作 1.准备打包好的apk(必须签名) test.apk 2.设备已经链接到电脑 具体操作 1.push apk ...

  3. Android ADB工具-管理设备 app(二)

    Android ADB工具-管理设备 app(二) 标签(空格分隔): Android 4.管理设备 app 命令 功能 adb install [-r|-s] <apkfile> 安装 ...

  4. android adb 模拟来电,在Android模拟器中模拟GPS、打电话、发短信……

    首先,当然要打开模拟器 然后,连接模拟器 C:\Users\BillGates>telnet localhost 5554 Android Console: type 'help' for a ...

  5. android adb模拟点击,Android adb 模拟滑动 按键 点击事件(示例代码)

    模拟事件全部是通过input命令来实现的,首先看一下input命令的使用: usage: input ... input text input keyevent input tap input swi ...

  6. android模拟power按键,Android adb 模拟滑动 按键 点击事件

    模拟事件全部是通过input命令来实现的,首先看一下input命令的使用: usage: input ... input text input keyevent input tap input swi ...

  7. 基于android驾校模拟考试系统app

    驾驶理论考试就是在线考试的一个实际应用,它实现了理论考试的无纸化,以往出题.印试卷.批改试卷等繁琐的工作,现在都可以由计算机来替代.本系统有驾校模拟考试功能,包括用户管理及试题库管理.试卷管理和随机出 ...

  8. android ADB 模拟手机点击事件

    手机连接到ADB 输入命令 adb shell getevent -p 显示 从这里可以知道每一个 /dev/input/event3: 0003 0035 00000161 event3是什么事件 ...

  9. Android adb 启动APP

    目录 启动命令 一 常规命令 + 包名/activity 二 常规命令 + 包名 命令关闭App 获取包名和activity的路径 代码获取 1 命令获取( 需要app运行在前台,停留在启动界面) 2 ...

最新文章

  1. 西湖大学全是“天坑”?校长施一公直播回应:不必过于关注就业收入
  2. 赠票 | 2019,GMIS归来!杨强、吴恩达等全球重磅嘉宾共话数据智能(上海)
  3. 使用 Servlet 读取表单数据
  4. 前端String类型转JSON类型
  5. ST-Link如何秒变J-link,手把手教你实现该功能
  6. Oracle 11g 新特性 -- 自适应游标共享(Adaptive Cursor Sharing: ACS) 说明
  7. 宁浩:扛过了,痛便是痛快!
  8. Simulink之交流调压电路
  9. 能自定义桌面后,iOS用户玩疯了
  10. mysql 冗余字段_18.3.3 增加冗余字段
  11. rsync同步目录及同步文件
  12. 【概率论与数理统计】1.2 概率的定义及其确定方法
  13. 主成分分析 SPSS、python实例分析
  14. 一套最有效的商业模式,老板贷款80万开火锅店,开业就回本?
  15. mybatis@Param的作用
  16. 【Java:JDBC+MySQL实现学生信息管理系统】
  17. 猿创征文 |汇编语言基础知识
  18. java 骑士飞行棋_C#实现骑士飞行棋
  19. 用“埃氏筛法”求2~10000以内的素数。2~100以内的数,先去掉2的倍数,再去掉3的倍数,再去掉5的倍数,……依此类推,最后剩下的就是素数。
  20. XStream 用法总结

热门文章

  1. 常用十大电子元器件有哪些?新手必读!
  2. VMware workstation 6.5.1 下载
  3. 视频教程-OpenCV图像分割实战视频教程-计算机视觉
  4. plc实验报告流程图_可编程控制器及应用实验报告.doc
  5. PyTorch faster_rcnn之一源码解读二 model_util
  6. Java项目:JSP宠物商城系统
  7. android手机可以换字体吗,安卓手机字体怎么改?安卓手机爱字体换字体教程
  8. MHDD工具使用简写
  9. mysql副本集_mongodb分片+副本集总览
  10. 计算机毕业设计基于springboot+vue+elementUI的网吧管理系统(源码+系统+mysql数据库+Lw文档)