用途:作为最基本的常规测试,全自动,用模拟器,4.4-7.0,开发包/混淆后的包会不会首屏闪退
会提到的小技术:
Appetizer 质量监控对 APK 进行 DEX 代码插桩,然后插装包运行时能监控质量(crash, http,卡顿等等),DEX 代码插桩是一个很底层的技术,大家有个疑问,插桩后会不会闪退啊,你们怎么确保这个事情的。我们的流程是这样的:
一般大家都用 Android Studio,点击 AVD Manager,额然后。。。 不,我们要全自动化
看一下所有 Android 工具链都是可以命令行执行的,从安装系统镜像,到造一个模拟器配置,到创建 sd 卡,到启动 emulator,因为 Google 内部,也有一套类似我们的全自动模拟器 headless 链。但是!但是!这套命令行特别难用,每次都要看一遍文档,所以我做了个包装,代码我放在这里了:https://github.com/appetizerio/haem
Headless Android Emulator Manager (haem)
Terminology: 只要记住四个概念
target - something like android-19 android-23 目标平台,比如android-19, android-23
abi - x86 x86_64 armeabi-v7a or arm64-v8 ABI,就是x86还是ARM,就这四种选择
avd - an arbitrary name for an Android Virtual Device (AVD) 模拟器配置名
port - every emulator listens on a local port, which can be inferred from its adb serialno, e.g., emulator-5444 模拟器的端口,比如emulator-5444端口对应就是5444
Usage: haem.py [OPTIONS] COMMAND [ARGS]... 好了,很简单,命令,参数和git一样
Options:
--help Show this message and exit.
Commands:
check 确认你的环境能否跑模拟器,没有参数
create 创建一个模拟器配置 参数 AVD TARGET 见上
delete 删除一个模拟器配置 参数 AVD
install 安装一个TARGET
list 列举现在已经创建的模拟器配置
running 用adb devices报告现在运行的模拟器
start 启动模拟器 参数AVD
stop 停止模拟器 参数PORT
如果对细节感兴趣的,看看这个的代码就知道了,Python 的,都是 stackoverflow 上行之有效的方法(比如好好退出我找了一阵子)
有了这个,一个脚本启动一麻袋模拟器(要记得自己的内存)
这个,有些坑
adb 安装再普通不过了,注意了,>=21(5.0)的时候要动态授权,所以最好在安装时用上-g,代码如下,不翻译了
# d 是设备串号,outpath是apk路径
opts = "-g " if int(apilevel) >= 21 else "" # grant all runtime permissions for api>=21
install_info = subprocess.check_output('adb -s %s install %s%s' % (d, opts, outpath), shell=True)
安装可能失败,找 install_info 里面有没有 Failure
清了 logcat 再启动,这个 Monkey 命令就帮你省了 activity 名(很多人会用 am)
# stage 2.2: clear logcat
subprocess.call('adb -s %s logcat -c' % (d, ), shell=True)
# launch it
subprocess.call("adb -s %s shell monkey -p %s 1" % (d, pkg), shell=True)
启动后 12 秒一般就够了,然后抓回来 logcat,-d
打印到屏幕走人
logcat_info = subprocess.check_output('adb -s %s logcat -d' % (d, ), shell=True)
先贴代码
# d是设备串号,pkg是apk的包名
wininfo = subprocess.check_output('adb -s %s shell dumpsys window windows' % (d, ), shell=True)
# stage 2.4: check if the app activity is focused
launched = False
for l in wininfo.splitlines():
if 'mCurrentFocus' in l and 'Application Error' in l:
launched = False
break
if 'mCurrentFocus' in l or 'mFocusedApp' in l:
launched = launched or pkg in l
首先 dumpsys window windows
这个命令会输出目前系统一层层的窗口层次(比如有 launcher,弹出框什么的),不详细解释了,有兴趣的可以去看一下,比较直观
重点是 mCurrentFocus(当前最上面的那个框)和 mFocusedApp(当前最上面的那个 APP)
有几种可能: