python自动化android应用性能测试(CPU、帧率、内存、数据流量、电量、电池温度)绘制为图表
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
测试狗一枚