def get_men(pkg_name, devices): """ 获取应用占用内存 adb -s 设备唯一标识(devices) shell dumpsys meminfo 包名(pkg_name) :param pkg_name: 被测应用包名 :param devices: 被测设备唯一标识 :return: """ try: logging.info('读取 ' + pkg_name + ' 内存占用') cmd = "adb -s " + devices + " shell dumpsys meminfo %s" % pkg_name logging.info(cmd) output = subprocess.check_output(cmd).split() if not output: raise ConnectAdbError s_men = ".".join([x.decode() for x in output]) # 转换为string logging.debug("s_men = " + s_men) men2 = int(re.findall("TOTAL.(\d+)*", s_men, re.S)[0]) except ConnectAdbError as e: logging.error(e) raise except Exception as e: logging.error(e) men2 = 0 logging.info('读取内存占用: ' + str(men2)) Pickle.write_info( men2, Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_men.pickle')) # Pickle.write_info(men2, PATH("../info/" + devices + "_men.pickle")) return men2
def get_fps(pkg_name, devices): """ 获取应用运行时的FPS adb -s 设备的唯一标识(devices) shell dumpsys gfxinfo 包名(pkg_name) :param pkg_name: 被测应用包名 :param devices: 被测设备的唯一标识 :return: """ logging.info('读取 ' + pkg_name + ' 运行时的FPS') try: _adb = "adb -s " + devices + " shell dumpsys gfxinfo %s" % pkg_name logging.info(_adb) results = os.popen(_adb).read().strip() if not results: raise ConnectAdbError logging.debug("results = " + results) frames = [x for x in results.split('\n') if validator(x)] logging.debug(frames) 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: 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)) except ConnectAdbError as e: logging.error(e) raise except Exception as e: logging.error(e) _fps = 0 logging.info('读取FPS: ' + str(_fps)) Pickle.write_info( _fps, Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_fps.pickle'))
def get_battery(devices): """ 获取设备当前电量 adb -s 设备唯一标识(devices) shell dumpsys battery :param devices: 被测设备唯一标识 :return: """ try: logging.info('获取设备的当前电量') cmd = "adb -s " + devices + " shell dumpsys battery" logging.info(cmd) output = subprocess.check_output(cmd).split() if not output: raise ConnectAdbError st = ".".join([x.decode() for x in output]) # 转换为string logging.debug("st = " + st) battery2 = int(re.findall("level:.(\d+)*", st, re.S)[0]) except ConnectAdbError as e: logging.error(e) raise except Exception as e: logging.error(e) battery2 = 90 logging.info('读取手机电量: ' + str(battery2)) # Pickle.write_info(battery2, PATH("../info/" + devices + "_battery.pickle")) Pickle.write_info( battery2, Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_battery.pickle')) return battery2
def mkdirInit(devices, app): # destroy(devices) # cpu = PATH("../info/" + devices + "_cpu.pickle") # men = PATH("../info/" + devices + "_men.pickle") # flow = PATH("../info/" + devices + "_flow.pickle") # battery = PATH("../info/" + devices + "_battery.pickle") # fps = PATH("../info/" + devices + "_fps.pickle") dev = ''.join(devices.split(':')) cpu = Path.info_path() + '\\' + dev + "_cpu.pickle" men = Path.info_path() + '\\' + dev + "_men.pickle" flow = Path.info_path() + '\\' + dev + "_flow.pickle" battery = Path.info_path() + '\\' + dev + "_battery.pickle" fps = Path.info_path() + '\\' + dev + "_fps.pickle" app[devices] = { "cpu": cpu, "men": men, "flow": flow, "battery": battery, "fps": fps, "header": get_phone(devices) } OperateFile(cpu).mkdir_file() OperateFile(men).mkdir_file() OperateFile(flow).mkdir_file() OperateFile(battery).mkdir_file() OperateFile(fps).mkdir_file() # OperateFile(PATH("../info/info.pickle")).remove_file() # OperateFile(PATH("../info/info.pickle")).mkdir_file() # 用于记录统计结果的信息,是[{}]的形式 OperateFile(Path.info_path() + '\\' + dev + "_info.pickle").remove_file() OperateFile(Path.info_path() + '\\' + dev + "_info.pickle").mkdir_file()
def get_flow(pd, devices): """ 获取应用的流量信息 adb -s 设备的唯一标识(devices) shell cat /proc/PID(pd)/net/dev :param pd: 应用的pid :param devices: 被测设备唯一标识 :return: """ logging.info('获取应用的流量信息') try: up_flow = down_flow = 0 if pd is not None: cmd = "adb -s " + devices + " shell cat /proc/" + pd + "/net/dev" logging.info(cmd) _flow = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines() logging.debug(_flow) for item in _flow: logging.debug(item.split()[0].decode()) if item.split()[0].decode() == "wlan0:": # wifi # 0 上传流量,1 下载流量 up_flow = int(item.split()[1].decode()) down_flow = int(item.split()[9].decode()) logging.debug('上行流量 : ' + str(up_flow)) logging.debug('下行流量 : ' + str(down_flow)) elif item.split()[0].decode() == "rmnet0:": # gprs logging.info("-----flow---------") up_flow = int(item.split()[1].decode()) down_flow = int(item.split()[9].decode()) logging.debug('上行流量 : ' + str(up_flow)) logging.debug('下行流量 : ' + str(down_flow)) # else: # up_flow = 0 # down_flow = 0 # logging.debug('上行流量 : '+str(up_flow)) # logging.debug('下行流量 : '+str(down_flow)) # break Pickle.write_flow_info( up_flow, down_flow, Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_flow.pickle')) except ConnectAdbError as e: logging.error(e) raise except Exception as e: logging.error('获取应用流量信息失败') logging.error(e)
def cpu_rate(pd, cpu_num, devices): """ 计算某进程的cpu使用率 100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,如果是多核情况下还需乘以cpu的个数); cpu_num cpu几核 pid 进程id :param pd: 应用运行的PID :param cpu_num: CPU个数 :param devices: 设备的唯一标识 :return: """ process_cpu_time1 = process_cpu_time(pd, devices) # print(process_cpu_time1) time.sleep(1) process_cpu_time2 = process_cpu_time(pd, devices) # print(process_cpu_time2) process_cpu_time3 = process_cpu_time2 - process_cpu_time1 # print(process_cpu_time3) total_cpu_time1 = total_cpu_time(devices) # print(total_cpu_time1) time.sleep(1) total_cpu_time2 = total_cpu_time(devices) # print(total_cpu_time2) total_cpu_time3 = (total_cpu_time2 - total_cpu_time1) * cpu_num # print(total_cpu_time3) logging.info("totalCpuTime3=" + str(total_cpu_time3)) logging.info("processCpuTime3=" + str(process_cpu_time3)) # try: # cpu = 100 * process_cpu_time3 / total_cpu_time3 # except: # cpu = 0 cpu = 100 * process_cpu_time3 / total_cpu_time3 # Pickle.write_info(cpu, PATH("../info/" + devices + "_cpu.pickle")) Pickle.write_info( cpu, Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_cpu.pickle')) logging.info("CPU使用率: " + str(cpu) + '%')
def start(devices): # num = devicess["num"] app = {} mkdirInit(devices, app) # mc = MonkeyConfig.monkey_config(Path.scan_files(postfix='.ini')) # 打开想要的activity # ba.open_app(mc["package_name"], mc["activity"], devices) 留着备用可以统计每次打开哪个页面的启动时间等 # monkey开始测试 log = Path.log_path() + "\\" + str(uuid.uuid4()) logging.debug('log路径 ' + log) monkey_log = log + "monkey.log" logging.debug('monkey日志路径: ' + monkey_log) package_name, monkey = Monkey_Config.monkey_config() # mc["cmd"] = mc['cmd'] + mc["monkey_log"] start_monkey("adb -s " + devices + " shell " + monkey + '>' + monkey_log, log) # start_monkey("adb -s " + devices + " shell " + mc["cmd"], mc["log"]) time.sleep(1) start_time = datetime.datetime.now() logging.info('测试开始时间 ' + str(start_time)) pid = Monitor.get_pid(package_name, devices) cpu_kel = Monitor.get_cpu_kel(devices) before_battery = Monitor.get_battery(devices) num = 0 while True: with open(monkey_log, encoding='utf-8') as monkeylog: time.sleep(1) # 每1秒采集检查一次 num = num + 1 Monitor.cpu_rate(pid, cpu_kel, devices) Monitor.get_men(package_name, devices) Monitor.get_fps(package_name, devices) Monitor.get_flow(pid, devices) Monitor.get_battery(devices) if monkeylog.read().count('Monkey finished') > 0: end_time = datetime.datetime.now() logging.info(str(devices) + "测试完成咯") app[devices]["header"]["beforeBattery"] = before_battery app[devices]["header"]["afterBattery"] = Monitor.get_battery( devices) app[devices]["header"]["monkey_log"] = monkey_log app[devices]["header"]["time"] = str( (end_time - start_time).seconds) + "秒" app[devices]['num'] = num write_info( app, Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_info.pickle')) monkeylog.close() break monkeylog.close() logging.info( read_info( Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_info.pickle'))) logging.info('测试结束。。。。。') report( read_info( Path.scan_files(select_path=Path.info_path(), postfix=''.join(devices.split(':')) + '_info.pickle')), devices)