def Create_pickle(dev, app, data): #------------------------------------------------------- new_dev = filter(dev) print("创建持久性文件...") cpu = PATH("./info/" + new_dev + "_cpu.pickle") men = PATH("./info/" + new_dev + "_men.pickle") flow = PATH("./info/" + new_dev + "_flow.pickle") battery = PATH("./info/" + new_dev + "_battery.pickle") fps = PATH("./info/" + new_dev + "_fps.pickle") time.sleep(2) app[dev] = { "cpu": cpu, "men": men, "flow": flow, "battery": battery, "fps": fps, "header": get_phone(dev) } OperateFile(cpu).mkdir_file() OperateFile(men).mkdir_file() OperateFile(flow).mkdir_file() OperateFile(battery).mkdir_file() OperateFile(fps).mkdir_file() OperateFile( PATH("./info/sumInfo.pickle")).mkdir_file() # 用于记录是否已经测试完毕,里面存的是一个整数 OperateFile( PATH("./info/info.pickle")).mkdir_file() # 用于记录统计结果的信息,是[{}]的形式 writeSum(0, data, PATH("./info/sumInfo.pickle")) # 初始化记录当前真实连接的设备数
def get_men(pkg_name, dev): men_list = [] cmd = "adb -s " + dev + " shell dumpsys meminfo " + pkg_name print(cmd) men_s = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines() for info in men_s: if len(info.split()) and info.split()[0].decode() == "TOTAL": men_list.append(int(info.split()[1].decode())) men = men_list[0] print("----men----") print(men) # --------------------------------------------------------------------------------------------------- new_dev = filter(dev) writeInfo(men, PATH("../info/" + new_dev + "_men.pickle")) return men
def get_battery(dev): battery = [] adb_battery = "adb -s " + dev + " shell dumpsys battery" print(adb_battery) _battery = subprocess.Popen(adb_battery, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines() for info in _battery: if info.split()[0].decode() == "level:": battery.append(int(info.split()[1].decode())) battery2 = battery[0] print("-----battery------") print(battery2) # --------------------------------------------------------------------------------------------------- new_dev = filter(dev) writeInfo(battery2, PATH("../info/" + new_dev + "_battery.pickle")) return battery2
def get_fps(pkg_name, dev): _adb = "adb -s " + dev + " shell dumpsys gfxinfo %s" % pkg_name print(_adb) results = os.popen(_adb).read().strip() frames = [x for x in results.split('\n') if validator(x)] frame_count = len(frames) jank_count = 0 vsync_overtime = 0 render_time = 0 for frame in frames: time_block = re.split(r'\s+', frame.strip()) if len(time_block) == 3: try: render_time = float(time_block[0]) + float(time_block[1]) + float(time_block[2]) except Exception as e: render_time = 0 ''' 当 大于16.67,按照垂直同步机制,该帧就已经渲染超时 那么,如果它正好是16.67的整数倍,比如66.68,则它花费了4个垂直同步脉冲,减去本身需要一个,则超时3个 如果它不是16.67的整数倍,比如67,那么它花费的垂直同步脉冲应向上取整,即5个,减去本身需要一个,即超时4个,可直接算向下取整 最后的计算方法思路: 执行一次命令,总共收集到了m帧(理想情况下m=128),但是这m帧里面有些帧渲染超过了16.67毫秒,算一次jank,一旦jank, 需要用掉额外的垂直同步脉冲。其他的就算没有超过16.67,也按一个脉冲时间来算(理想情况下,一个脉冲就可以渲染完一帧) 所以FPS的算法可以变为: m / (m + 额外的垂直同步脉冲) * 60 ''' if render_time > 16.67: jank_count += 1 if render_time % 16.67 == 0: vsync_overtime += int(render_time / 16.67) - 1 else: vsync_overtime += int(render_time / 16.67) _fps = int(frame_count * 60 / (frame_count + vsync_overtime)) print("-----fps------") print(_fps) # ---------------------------------------------------------------------------------------------------------------------------------------------------------- new_dev = filter(dev) writeInfo(_fps, PATH("../info/" + new_dev + "_fps.pickle")) return _fps
def cpu_rate(pid, cpukel, dev): # pid = get_pid(pkg_name) processCpuTime1 = processCpuTime(pid, dev) time.sleep(1) processCpuTime2 = processCpuTime(pid, dev) processCpuTime3 = processCpuTime2 - processCpuTime1 totalCpuTime1 = totalCpuTime(dev) time.sleep(1) totalCpuTime2 = totalCpuTime(dev) totalCpuTime3 = (totalCpuTime2 - totalCpuTime1) * cpukel # print("totalCpuTime3=" + str(totalCpuTime3)) # print("processCpuTime3=" + str(processCpuTime3)) cpu = 100 * (processCpuTime3) / (totalCpuTime3) print("--------cpu--------") print(cpu) # --------------------------------------------------------------------------------------------------------------------------------- new_dev = filter(dev) writeInfo(cpu, PATH("../info/" + new_dev + "_cpu.pickle")) return cpu
def get_flow(pid, type, dev): # pid = get_pid(pkg_name) upflow = downflow = 0 if pid is not None: cmd = "adb -s " + dev + " shell cat /proc/" + pid + "/net/dev" print(cmd) _flow = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines() for item in _flow: if type == "wifi" and item.split()[0].decode() == "wlan0:": # wifi # 0 上传流量,1 下载流量 upflow = int(item.split()[9].decode()) downflow = int(item.split()[1].decode()) if type == "gprs" and item.split()[0].decode() == "rmnet0:": # gprs upflow = int(item.split()[9].decode()) downflow = int(item.split()[1].decode()) print("------flow---------") print(upflow, downflow) # --------------------------------------------------------------------------------------------------------------------------------- new_dev = filter(dev) writeFlowInfo(upflow, downflow, PATH("../info/" + new_dev + "_flow.pickle"))
def start(dev): rt = os.popen('adb devices').readlines() # os.popen()执行系统命令并返回执行后的结果 num = len(rt) - 2 print(num) app = {} Create_pickle(dev, app, num) """os.popen("adb kill-server") os.popen("adb start-server") time.sleep(5)""" # 手动测试部分(手动测试性能数据统计),直接杀掉app进程即可结束测试统计(备注:操作过程中请不要杀掉app进程,否则测试终止) """signal = input("现在是手动测试部分,是否要开始你的测试,请输入(y or n): ") if signal == 'y': print("测试即将开始,请打开需要测试的app并准备执行您的操作....") time.sleep(5) path_log = Config.log_location + dev device_dir = os.path.exists(path_log) if device_dir: print("日志文件目录log已存在,继续执行测试!") else: os.mkdir(path_log) # 按设备ID生成日志目录文件夹 run_time = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) # logcat日志 logcat_log = path_log + "\\" + run_time + "logcat.log" cmd_logcat = "adb -s " + dev + " logcat > %s" % (logcat_log) os.popen(cmd_logcat) # print("logcat 命令:", cmd_logcat) # "导出traces文件" traces_log = path_log + "\\" + run_time + "traces.log" cmd_traces = "adb -s " + dev + " shell cat /data/anr/traces.txt > %s" % traces_log os.popen(cmd_traces) # print("traces 命令:", cmd_traces) time.sleep(2) start_time = datetime.datetime.now() pid = BaseMonitor.get_pid(Config.package_name, dev) cpu_kel = BaseMonitor.get_cpu_kel(dev) beforeBattery = BaseMonitor.get_battery(dev) print("测试前电量", beforeBattery) try: while True: time.sleep(1) # 每1秒采集一次 print("----------------数据采集-----------------") BaseMonitor.cpu_rate(pid, cpu_kel, dev) BaseMonitor.get_men(Config.package_name, dev) BaseMonitor.get_fps(Config.package_name, dev) BaseMonitor.get_flow(pid, Config.net, dev) BaseMonitor.get_battery(dev) except: end_time = datetime.datetime.now() print(str(dev) + ":测试完成!") afterBattery = BaseMonitor.get_battery(dev) writeSum(1, path=PATH("./info/sumInfo.pickle")) app[dev]["header"]["beforeBattery"] = beforeBattery app[dev]["header"]["afterBattery"] = afterBattery app[dev]["header"]["net"] = Config.net app[dev]["header"]["time"] = str((end_time - start_time).seconds) + "秒" writeInfo(app, PATH("./info/info.pickle")) if readInfo(PATH("./info/sumInfo.pickle")) <= 0: report(readInfo(PATH("./info/info.pickle"))) print("Kill adb server,test finished!") os.popen("taskkill /f /t /im adb.exe") shutil.rmtree((PATH("./info/"))) # 删除持久化目录 elif signal == 'n': print('用户主动放弃测试,测试结束!') else: print("测试结束,输入非法,请重新输入y or n!")""" # Monkey测试部分,如果是进行monkey测试,去除该部分注释(line134~line191)并注掉手动测试部分(line72~line131);另外BaseReport.py中line85,line120~line132注释也要去除 print("--------------开始执行Monkey----------------") new_dev = filter(dev) path_log = Config.log_location + new_dev device_dir = os.path.exists(path_log) if device_dir: print("日志文件目录log已存在,继续执行测试!") else: os.mkdir(path_log) # 按设备ID生成日志目录文件夹 run_time = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) # Monkey测试结果日志:monkey_log adb_monkey = "shell monkey -p %s -s %s %s" % ( Config.package_name, Config.monkey_seed, Config.monkey_parameters) monkey_log = path_log + "\\" + run_time + "monkey.log" cmd_monkey = "adb -s %s %s > %s" % (dev, adb_monkey, monkey_log) os.popen(cmd_monkey) print("monkey 命令:", cmd_monkey) # logcat日志 logcat_log = path_log + "\\" + run_time + "logcat.log" cmd_logcat = "adb -s " + dev + " logcat > %s" % (logcat_log) os.popen(cmd_logcat) # print("logcat 命令:", cmd_logcat) # "导出traces文件" traces_log = path_log + "\\" + run_time + "traces.log" cmd_traces = "adb -s " + dev + " shell cat /data/anr/traces.txt > %s" % traces_log os.popen(cmd_traces) # print("traces 命令:", cmd_traces) time.sleep(2) start_time = datetime.datetime.now() pid = BaseMonitor.get_pid(Config.package_name, dev) cpu_kel = BaseMonitor.get_cpu_kel(dev) beforeBattery = BaseMonitor.get_battery(dev) print("测试前电量", beforeBattery) while True: try: with open(monkey_log, encoding='utf-8') as monkeylog: time.sleep(2) # 每2秒采集一次 print("----------------数据采集-----------------") BaseMonitor.cpu_rate(pid, cpu_kel, dev) BaseMonitor.get_men(Config.package_name, dev) BaseMonitor.get_fps(Config.package_name, dev) BaseMonitor.get_flow(pid, Config.net, dev) BaseMonitor.get_battery(dev) if monkeylog.read().count('Monkey finished') > 0: end_time = datetime.datetime.now() print(str(dev) + ":测试完成!") afterBattery = BaseMonitor.get_battery(dev) writeSum(1, path=PATH("./info/sumInfo.pickle")) app[dev]["header"]["beforeBattery"] = beforeBattery app[dev]["header"]["afterBattery"] = afterBattery app[dev]["header"]["net"] = Config.net app[dev]["header"]["monkey_log"] = monkey_log app[dev]["header"]["time"] = str( (end_time - start_time).seconds) + "秒" writeInfo(app, PATH("./info/info.pickle")) break except: end_time = datetime.datetime.now() print(str(dev) + ":测试完成!") afterBattery = BaseMonitor.get_battery(dev) writeSum(1, path=PATH("./info/sumInfo.pickle")) app[dev]["header"]["beforeBattery"] = beforeBattery app[dev]["header"]["afterBattery"] = afterBattery app[dev]["header"]["net"] = Config.net app[dev]["header"]["monkey_log"] = monkey_log app[dev]["header"]["time"] = str( (end_time - start_time).seconds) + "秒" writeInfo(app, PATH("./info/info.pickle")) break if readInfo(PATH("./info/sumInfo.pickle")) <= 0: report(readInfo(PATH("./info/info.pickle"))) print("Kill adb server,test finished!") os.popen("taskkill /f /t /im adb.exe") shutil.rmtree((PATH("./info/"))) # 删除持久化目录