我们在android端性能测试的时候,经常需要查看设备性能运行的情况,市面上比较好用的工具有iTEST、PerfDog、Solopi等;
但是大多数都没有API模式接入、比如在自动化测试时同时获取性能相关信息就比较棘手了;
本篇讲解使用python通过adb模式获取设备性能数据;
注意:目前只适配了华为mate9,其他手机需要微调下脚本即可
1.数据来源主要是如何获取性能数据,采用adb模式获取:
2.分别对应adb命令及用法:
CPU数据:
#获取包占用cpu
adb -s 设备id shell COLUMNS=512 top |findstr "应用包名"
#获取设备cpu
adb -s 设备id shell COLUMNS=512 top
#获取包占用cpu和设备空闲cpu
adb -s 设备id shell COLUMNS=512 top |findstr "应用包名 空闲标识"
#获取一次包占用cpu和设备空闲cpu
adb -s 设备id shell COLUMNS=512 top -n 1 |findstr "包名 idle"
#监测一次应用CPU的占用情况
adb -s 设备id shell COLUMNS=512 top -n 1 |findstr 包名
#10秒刷新一次显示CPU占用情况
adb -s 设备id shell top -d 10 |findstr 包名
备注:
1.空闲标识就是top第三行cpu概述中可用的cpu资源
2.top命令在虚拟终端中输出,top主动截断了超过宽度的字符,,所有需要调大指定512个字符 COLUMNS=512
3.获取cpu可以用adn shell dumpsys cpuinfo |findstr 包名 ,,但推荐用top方法
4.空闲标识就是cpu中的idle字段
内存:
#_____________________________使用dumpsys meminfo方式查看内存________________________
#获取应用占用的内存
adb -s 设备id shell dumpsys meminfo 包名 |findstr TOTAL
#获取设备可用内存
adb -s 设备id shell dumpsys meminfo |findstr Free
#获取设备总内存
adb -s 设备id shell dumpsys meminfo |findstr "Total"
#_______________________________直接在设备获取内存文件(推荐使用)________________________________
#获取设备内存信息
adb -s 设备id shell cat /proc/meminfo
#获取设备总内存
adb -s 设备id shell cat /proc/meminfo |findstr "MemTotal"
#获取设备可用内存
adb -s 设备id shell cat /proc/meminfo |findstr "MemAvailable"
#获取设备总内存和剩余可用内存
adb -s 设备id shell cat /proc/meminfo |findstr "MemTotal MemAvailable"
电量电池温度:
#获取设备电池信息
adb -s 设备id shell dumpsys battery
#结果解释:
Current Battery Service state:
AC powered: false #是否交流供电
USB powered: true #是否usb供电
Wireless powered: false #是否无线供电
status: 2 #电池状态
health: 2
present: true
level: 34 #电量
scale: 100
voltage: 3848
current now: -427943
temperature: 280 #电池温度
technology: Li-ion
帧率:
#获取包的帧率
adb -s 设备id shell dumpsys gfxinfo 包名
注意:帧率只有在界面变化时才出现
上下行流量:
#获取包的流量
adb -s 设备id shell cat /proc/13478/net/dev
步骤:
1.先找到包对应的pid: adb -s 设备id shell ps |findstr 包名
2.然后执行,就能获得包的流量:adb -s 设备id shell cat /proc/PID/net/dev
1、receive是指当前进程接收的数据(下行流量),transmit是指当前进程发出请求的数据(上行流量),流量是这两者之和。
2、wlan0代表WiFi,单位是字节,/1024可换算成KB。
3、wlan0如何初始化0 只需打开手机飞行模式再关掉就清0了。
帧率:
#!/usr/bin/python
# coding:utf-8
import os, re, sys
from time import sleep
def parseFPS(device_id,pkg):
# pkg是包名
# 可以用 adb shell pm list packages 查看所有的包
# 获取对应包的gfxinfo
info = os.popen('adb -s {} shell dumpsys gfxinfo {}'.format(device_id,pkg)).read()
# 拿到里面的总渲染帧率和系统时间
result = re.findall(r'Realtime: (\d*)|Total frames rendered: (\d*)', info)
realtime0 = int(result[0][0])
frames0 = int(result[1][1])
while True:
info = os.popen('adb -s {} shell dumpsys gfxinfo {}'.format(device_id,pkg)).read()
result = re.findall(r'Realtime: (\d*)|Total frames rendered: (\d*)', info)
# 循环获取帧率和时间
# 帧率 = 相差帧率/时间间隔
realtime1 = int(result[0][0])
frames1 = int(result[1][1])
frames = frames1 - frames0
times = realtime1 - realtime0
print('FPS: %.2f'%(frames / (times / 1000)))
print('----')
# 间隔0.5s获取数据
sleep(1)
frames0, realtime0 = frames1, realtime1
if __name__ == "__main__":
device_id='QFF0219925011304'
packagename='com.shywlhy.shhsl.toutiao'
parseFPS(device_id,packagename)
####外界调用(调用方法 python test.py packagename)
# if len(sys.argv) == 1:
# sys.exit(0)
# else:
# try:
# parseFPS(sys.argv[1])
# except Exception as e:
# print(e)
电量和电池温度:
#!/usr/bin/env python
# encoding: utf-8
import os
import subprocess
def battery_text(device_id):
'''获取电量和电池温度'''
try:
p1 = subprocess.Popen('adb -s {} shell dumpsys battery|findstr "temperature level"'.format(device_id) ,
stdout=subprocess.PIPE, shell=True) # 用adb获取信息
process_str = p1.stdout.read()
pid_str = str(process_str, encoding = "utf8")
#分割后得到一个列表
pid_list=pid_str.split()
level=int(pid_list[1])
temperature=int(pid_list[3])/10
return level,temperature
except Exception as e:
print(e,":get_packagename_pid,请检查包名是否正确,是否已启动包名………")
应用上下行流量:
#!/usr/bin/env python
# encoding: utf-8
__author__ = "晨晨"
import re
import os
import time
import subprocess
from subprocess import Popen, PIPE
def get_packagename_pid(device_id,packagename):
'''获取包对应的pid'''
try:
p1 = subprocess.Popen('adb -s {} shell ps|findstr {}'.format(device_id,packagename) ,
stdout=subprocess.PIPE, shell=True) # 用adb获取信息
process_str = p1.stdout.read()
pid_str = str(process_str, encoding = "utf8")
#分割后得到一个列表
pid_list=pid_str.split()
return pid_list[1]#第一个元素是pid
except Exception as e:
print(e,":get_packagename_pid,请检查包名是否正确,是否已启动包名………")
def get_flow(device_id,pid):
'''通过pid获取上下行流量'''
try:
p1 = subprocess.Popen('adb -s {} shell cat /proc/{}/net/dev '.format(device_id,pid) ,
stdout=subprocess.PIPE