1.实现功能
使用python自动化对android应用进行性能测试,将CPU、帧率、内存、数据流量、电量、电池温度数据绘制为图表
测试获取数据,每秒1次
记录测试数据
绘制为图表
代码部分
1.获取数据代码(Perf_DataTest.py)
#!/user/bin/env python3
# -*- coding: utf-8 -*-
import os,re
import time
import datetime
import subprocess
import numpy as np
from subprocess import Popen, PIPE
import logging
if os.path.exists(os.getcwd() + "/test_data"):
pass
else:
os.makedirs(os.getcwd() + "/test_data")
csv = logging.getLogger()
csv.setLevel(logging.DEBUG)
fh= logging.FileHandler(os.getcwd() + "/test_data/"+time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) + '.csv')
fh.setLevel(logging.INFO)
ch= logging.StreamHandler()
ch.setLevel(logging.INFO)
formatter = logging.Formatter()
ch.setFormatter(formatter)
fh.setFormatter(formatter)
csv.addHandler(ch)
csv.addHandler(fh)
def get_mem(package):
try:
cmd = r'adb shell dumpsys meminfo ' + package + ' | findstr "TOTAL"' # % apk_file
total = str((os.popen(cmd).readlines()))
return (re.findall(r"\d+\.?\d*", total)[0])
except Exception as e:
print(str(e),"get_mem(package),请检查包名是否正确……")
return -1
def dump_layer_stats(str_command):
L = []
p = Popen(str_command, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
for line in p.stdout:
if line != '\n':
ldata1 =(line[:-1].split('\t'))
ldata=[]
for i in ldata1:
ldata.append(int(i))
if len(ldata)== 1:
pass
else:
if (ldata[1]) >= 9223372036854775807:
continue
elif (ldata[1]) == 0:
continue
L.append((ldata[1]))
# p.terminate()
return L
def get_fps(str_command):
while True:
L =dump_layer_stats(str_command)
size = len(L)
interval = 0
if size > 0:
interval = L[size - 1] - L[0]
else:
#print("get_fps(str_command),请使用adb shell dumpsys SurfaceFlinger更新SurfaceView名称")
return -1#(获取不到异常)
if interval == 0:
continue
fps = 1000000000 * (size - 1) / interval
return round(fps)
def get_battery():
try:
cmd = 'adb shell dumpsys battery' # % apk_file
redcmd = str((os.popen(cmd).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("[",
" ")
battery_dic = {}
redcmd = (redcmd).split("n', '")[0].split(',')
for i in redcmd[1:]:
if ":" in i:
b_dic = {i.split(":")[0].replace(" ", ""): i.split(":")[1]}
battery_dic.update(b_dic)
return battery_dic
except Exception as e:
print(e,"get_battery(),请检查包名是否正确……")
bat_dic={'ACpowered': ' false ',
'USBpowered': ' false ',
'Wirelesspowered': ' false ',
'Maxchargingcurrent': ' 0 ',
'Maxchargingvoltage': ' 0 ',
'Chargecounter': ' 2172420 ',
'status': ' 3 ',
'health': ' 2 ',
'present': ' true ',
'level': ' -1 ',
'scale': ' 100 ',
'voltage': ' 3843 ',
'temperature': ' -1 ',
'technology': ' Li-poly '}
return bat_dic
def getUid(package_name):#获取UID
try:
p1 = subprocess.Popen('adb shell dumpsys package ' + package_name + ' | grep "userId"',
stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 用adb获取信息
uidLongString = p1.stdout.read()
uidLongList = uidLongString.split()
uidMap = uidLongList[0]
uid = str(uidMap).split("=")[1].replace("'", "")
return uid
except Exception as e:
print(e,"getUid(),请检查包名是否正确……")
def getRev(Uid):
try:
rx_bytes = []
tx_bytes = []
rx_tcp_bytes = []
tx_tcp_bytes = []
cmd = 'adb shell "cat /proc/net/xt_qtaguid/stats | grep %s"' % (Uid)
redcmd = str((os.popen(cmd).readlines())).replace("['", '').replace("]", '').replace("\\n'", '').replace("'",
"").split(
",")
for r in redcmd:
red = r.split(" ")
red = [i for i in red if i != '']
rx_bytes.append(int(red[5]))
tx_bytes.append(int(red[7]))
rx_tcp_bytes.append(int(red[9]))
tx_tcp_bytes.append(int(red[15]))
# dics={
# "rx_bytes":sum(rx_bytes),
# "tx_bytes": sum(tx_bytes),
# "rx_tcp_bytes":sum(rx_tcp_bytes),
# "tx_tcp_bytes":sum(tx_tcp_bytes),
# }
listdic = [sum(rx_bytes), sum(tx_bytes), sum(rx_tcp_bytes), sum(tx_tcp_bytes), ]
return listdic
except Exception as e:
print(e,"getRev(package_name),请检查包名是否正确……")
return [-1,-1,-1,-1]
def get_cpu(pid):
try:
cmd = 'adb shell "cat /proc/stat | grep ^cpu"' # % apk_file
cmd1 = 'adb shell cat /proc/%s/stat' % (pid)
redcmd = str((os.popen(cmd).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("[",
" ")
redcmd = [i for i in redcmd.split(",")[0].split(" ") if i != '']
redcmd.remove(redcmd[0])
del redcmd[-3:]
total_cpu = sum(list(map(int, redcmd)))
idle=redcmd[3]
redcmd1 = str((os.popen(cmd1).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("[",
" ").split(
" ")[14:18]
pjiff=sum(list(map(int, redcmd1)))
return [total_cpu,idle,pjiff]
except Exception as e:
print(e,"get_s_cpu(),检查adb是否连通……")
return [-1,-1,-1,-1,-1,-1,-1]
def get_Screen():
try:
cmd = 'adb shell "dumpsys window policy|grep isStatusBarKeyguard"' # % apk_file
redcmd = str((os.popen(cmd).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("["," ").split("=")[-1]
return (redcmd)
except Exception as e:
print(e,"get_Screen(),检查adb是否连通……")
def get_iphoneinfo():
try:
dics={}
cmd ='adb shell "getprop | grep product"'
redcmd= str((os.popen(cmd).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("["," ").replace(" ","").split(",")
for i in redcmd:
if ":" in i:
dic={i.split(":")[0]:i.split(":")[-1]}
dics.update(dic)
cmd1 ='adb shell cat /proc/meminfo'
redcmd1= str((os.popen(cmd1).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("["," ").replace(" ","").split(",")[0]
pp,cupxh,mmet=(dics["ro.product.manufacturer"].title() +" "+ dics['ro.product.model'], dics['ro.product.board'],
str(round(int(re.findall(r"\d+\.?\d*", redcmd1)[0]) / 1024 / 1024)) + "G")
return ("%s;%s;%s"%(pp,cupxh,mmet))
except Exception as e:
print(str(e),"get_mem(package),请检查adb是否连通……")
return 'xxxxx'
def get_PID(package):
if int(str((os.popen("adb shell getprop ro.build.version.release").readlines())).replace("'", "").replace("\\n"," ").replace(
"]", " ").replace("[", " ").split('.')[0]) >= 8:
cmd = "adb shell ps -A"
else:
cmd="adb shell ps"
try:
pid=[]
redcmd = str((os.popen(cmd).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("["," ").split(",")
for n in redcmd:
if package in n:
list_n = [i for i in n.split(" ") if i != ''] # 删除空元素
if package == list_n[-1]:
pid.append(list_n[1])
return pid[0]
except Exception as e:
print(str(e), "get_mem(package),请检查adb是否连通……")
return 'xxxxx'
def SumDic(package):
Uid=getUid(package)
pid=get_PID(package)
net1 = np.array(getRev(Uid))#流量
total_cpu1,idle1,pjiff1= get_cpu(pid)
str_command = get_cmmand(package)
iphone_info=get_iphoneinfo()
bt = "'time','iphone_info', 'package', 'mem', 'cpu', 'systemCpu', 'rxBytes', 'txBytes', 'rxTcpBytes', 'txTcpBytes', 'fps', 'level','batterytem'".replace("'", "").replace(" ", "")
csv.info(bt)
while True:
timestr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
mem = round(int(get_mem(package)) / 1024, 3)
fps = get_fps(str_command)
level = int(get_battery()['level'])
batterytem = int(get_battery()['temperature']) / 10
total_cpu2,idle2,pjiff2= get_cpu(pid)
net2 = np.array(getRev(Uid)) # 流量
pcpu = 100.0 * (int(pjiff2) - int(pjiff1)) / (int(total_cpu2) - int(total_cpu1)) # process cpu
systemCpu =100.0 * ((int(total_cpu2) - int(idle2)) -(int(total_cpu1) - int(idle1))) / (int(total_cpu2) - int(total_cpu1)) # system cpu
rbytes, tbytes, rtcp, ttcp = (net2 - net1) # 流量
total_cpu1,idle1,pjiff1 = total_cpu2,idle2,pjiff2
net1 = net2
sumdic = {
"time": timestr,
"iphone_info":iphone_info,
'package': package,
"mem": mem,
"cpu": round(pcpu,2),
"systemCpu": round(systemCpu,2),
'rxBytes': round(rbytes / 1024, 3),
'txBytes': round(tbytes / 1024, 3),
'rxTcpBytes': round(rtcp / 1024, 3),
'txTcpBytes': round(ttcp / 1024, 3),
"fps": fps,
"level": level,
"batterytem": batterytem,
}
list_v = str(list(sumdic.values())).replace("[", "").replace("]", "").replace("'", "")
csv.info(list_v)
#logger.info(sumdic)
def get_Activity(package):
try:
cmd = 'adb shell dumpsys SurfaceFlinger --list' # % apk_file
redcmd =str((os.popen(cmd).readlines())).replace("'", "").replace("\\n", " ").replace("]", " ").replace("[", " ").split(" ")
listpack=[]
for i in redcmd:
if package in i:
listpack.append(i)
return max_list(listpack).replace(" ","")
except Exception as e:
print(str(e),"get_mem(package),请检查adb是否连接……")
def max_list(lt):
temp = 0
for i in lt:
if lt.count(i) > temp:
max_str = i
temp = lt.count(i)
return max_str
def get_cmmand(package):
str_command0 = 'adb shell dumpsys SurfaceFlinger --latency SurfaceView\ -\ %s'%(get_Activity(package))
str_command1 = 'adb shell dumpsys SurfaceFlinger --latency SurfaceView %s'%(get_Activity(package))
str_command2 = 'adb shell dumpsys SurfaceFlinger --latency %s'%(get_Activity(package))
list_cmd = [str_command0, str_command1, str_command2]
for i in list_cmd:
if int(get_fps(i))!=-1:
return i
if __name__ == '__main__':
#os.system('adb connect 192.168.1.98:5555')#连接WiFi连通adb
package = 'com.tencent.tmgp.sgame'#com.tencent.tmgp.sgame,com.example.helloAR
SumDic(package)
2.绘制图表代码(Data_Charts.py)
import os,time
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import datetime
import humanize
def csv2images(src):
target_dir=os.getcwd()
package_name,iphone_info=tets_info(src)
"""
Args:
src: csv file, default to perf record csv path
target_dir: images store dir
"""
plt.figure(figsize=(19.20, 10.80))
if not os.path.exists(target_dir):
os.makedirs(target_dir)
data = pd.read_csv(src)
data['time'] = data['time'].apply(
lambda x: datetime.datetime.strptime(x,"%Y-%m-%d %H:%M:%S.%f")) # time.strftime("%Y/%m/%d/%H/%M/%S", time.localtime()) %Y-%m-%d %H:
# #timestr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
timestr = time.strftime("%Y-%m-%d %H:%M")
# network
rx_str = round(data['rxBytes'].sum(), 2)
tx_str = round(data['txBytes'].sum(), 2)
plt.subplot(7, 1, 1)
plt.plot(data['time'], data['rxBytes'], label='all')
plt.plot(data['time'], data['rxTcpBytes'], 'r--', label='tcp')
plt.legend()
plt.title(
'\n'.join(
["Summary",iphone_info,src.split("/")[-1], package_name, timestr,
'Recv %s KB, Send %s KB' % (rx_str, tx_str)]),
loc='left')
plt.gca().xaxis.set_major_formatter(ticker.NullFormatter())
plt.ylabel('Recv(KB)')
plt.ylim(ymin=0)
plt.subplot(7, 1, 2)
plt.plot(data['time'], data['txBytes'], label='all')
plt.plot(data['time'], data['txTcpBytes'], 'r--', label='tcp')
plt.legend()
# plt.xlabel('Time')
plt.ylabel('Send(KB)')
plt.ylim(ymin=0)
plt.gca().xaxis.set_major_formatter(ticker.NullFormatter())
# .clf()
plt.subplot(7, 1, 3)
plt.plot(data['time'], data['mem'], '-')
plt.ylabel('mem(MB)')
plt.gca().xaxis.set_major_formatter(ticker.NullFormatter())
plt.subplot(7, 1, 4)
plt.plot(data['time'], data['cpu'], 'r--', label='cpu') # systemCpu
plt.plot(data['time'], data['systemCpu'], label='systemCpu') # systemCpu
plt.legend()
plt.ylim(0, max(100, data['cpu'].max()))
plt.ylabel('CPU')
plt.ylim(ymin=0)
plt.gca().xaxis.set_major_formatter(ticker.NullFormatter())
plt.subplot(7, 1, 5)
plt.plot(data['time'], data['fps'], '-')
plt.ylabel('FPS')
plt.ylim(-1, 60)
plt.gca().xaxis.set_major_formatter(ticker.NullFormatter())
plt.subplot(7, 1, 6)
plt.plot(data['time'], data['level'], '-')
plt.ylabel('level')
plt.ylim(0, 110)
plt.gca().xaxis.set_major_formatter(ticker.NullFormatter())
plt.subplot(7, 1, 7)
plt.plot(data['time'], data['batterytem'], '-')
plt.ylim(0, 100)
plt.ylabel('BatteryTem')
plt.xlabel('Time')
plt.savefig(os.path.join(target_dir, src.split("/")[-1].split('.')[0]+".png"))
def tets_info(src):
data = pd.read_csv(src)
pack=(data['package'][0]).replace(" ",'')
iphone=(data['iphone_info'][0])
return [pack,iphone]
if __name__ == '__main__':
#src = input('请将csv文件拖入窗口,并点击回车!!!!!\n\n')
#src = '20200113104916.csv'
src =(os.getcwd() + "/test_data/"+os.listdir((os.getcwd() + "/test_data"))[-1])
print(src)
csv2images(src)
#input(".............................")
————————————————
版权声明:本文为CSDN博主「默金……」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42846555/article/details/103970212