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 __init__(self): global case try: self.data = xlrd.open_workbook(Path.scan_files(postfix='case.xls')) case = self.data.sheet_by_name(u'测试用例') self.case_num = case.nrows # 测试用例行数 except Exception as e: creat_case.exception_handling(e) raise Custom_exception.OpenXlsError
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 __init__(self): try: desired_caps = {} desired_caps['platformName'] = 'Android' desired_caps['platformVersion'] = Get_Phone.get_android_version() # 设备版本 desired_caps['deviceName'] = Get_Phone.get_device_name() # 设备名称 desired_caps['app'] = PATH(Path.scan_files(postfix='.apk')) # 待测应用 # desired_caps['appPackage'] = 'com.sixty.nidoneClient' # desired_caps['appActivity'] = 'com.sixty.nidoneClient.view.activity.SDK_WebApp' desired_caps['unicodeKeyboard'] = True desired_caps['resetKeyboard'] = True # 如果设置的是app在电脑上的路径,则不需要配appPackage和appActivity,同理反之 self.driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps) except Exception as e: creat_case.exception_handling(e) raise Custom_exception.GetDriverError
def __init__(self): config = configparser.ConfigParser() config.read(Path.scan_files(prefix='email_address')) try: # 发件人地址 self.Sender = config['email_address']['Sender'] # 收件人地址,多个收件人用逗号隔开 self.Addressee = config['email_address']['Addressee'] # 第三方smtp,例如网易的,smtp.163.com self.smtp = config['email_address']['smtp'] # 授权登录账号 self.login = config['email_address']['login'] # 授权码 self.AuthorizationCode = config['email_address'][ 'AuthorizationCode'] except Exception as e: creat_case.exception_handling(e, "邮件信息初始化") raise Custom_exception.MailInitializationError
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 test_case(): global l case_excel = ReadData.ReadCaseExcel() ob = ReadData.ReadStepExcel() fist, end = run_list.test_case_list(case_excel.case_num) l = ReadData.ReadCaseExcel.result_list(fist, end) try: f = open(Path.scan_files(prefix='Test_Case'), 'w') except Exception as e: raise Custom_exception.CreatTestCaseError f.write('#! /usr/bin/python\n') f.write('# -*- coding:utf-8 -*-\n') f.write('import unittest\n') f.write('from common import log\n') f.write('from common import operation\n') f.write('from common import creat_case\n') f.write('# 测试用例\n') f.write('\n') f.write('\n') f.write('class ParametrizedTestCase(unittest.TestCase):\n') f.write(' """ TestCase classes that want to be parametrized should\n') f.write(' inherit from this class.\n') f.write(' """\n') f.write(' def __init__(self, method_name="runTest", run_time=None):\n') f.write( ' super(ParametrizedTestCase, self).__init__(method_name)\n') f.write(' self.method_name = method_name\n') f.write('\n') f.write('\n') f.write('class Test(ParametrizedTestCase):\n') f.write(' def setUp(self):\n') f.write(' self.OP = operation.Opera()\n') f.write('\n') f.write(' def tearDown(self):\n') f.write(' self.OP.quit()\n') for i in range(fist, end): f.write('\n') f.write(' @log.deco(u"%s")\n' % ob.get_case_desc(i)[1]) f.write(' def %s(self):\n' % ob.get_case_desc(i)[2]) f.write(' try:\n') for j in range(3, len(ob.get_case_desc(i))): # 等待 if ob.get_case_desc(i)[j][1] == 'sleep': f.write(' time.sleep(%s)\n' % ob.get_case_desc(i)[j][4]) # 切换 h5 elif ob.get_case_desc(i)[j][1] == 'sw_h5': f.write(' self.OP.sw_h5()\n') # 切换app elif ob.get_case_desc(i)[j][1] == 'sw_app': f.write(' self.OP.sw_app()\n') # 输入 elif ob.get_case_desc(i)[j][1] == 'send_keys': f.write(' self.OP.send_keys("%s", "%s", "%s")\n' % (ob.get_case_desc(i)[j][2], ob.get_case_desc(i)[j][3], ob.get_case_desc(i)[j][4])) # 点击 elif ob.get_case_desc(i)[j][1] == 'clicks': f.write(' self.OP.clicks("%s", "%s")\n' % (ob.get_case_desc(i)[j][2], ob.get_case_desc(i)[j][3])) # 等待 elif ob.get_case_desc(i)[j][1] == 'wait_element': f.write(' self.OP.wait_element("%s", "%s")\n' % (ob.get_case_desc(i)[j][2], ob.get_case_desc(i)[j][3])) # 物理键返回 elif ob.get_case_desc(i)[j][1] == 'go_back': f.write(' self.OP.go_back()\n') # 向上滑动 elif ob.get_case_desc(i)[j][1] == 'swipe_up': f.write(' self.OP.swipe_up()\n') # 向下滑动 elif ob.get_case_desc(i)[j][1] == 'swipe_to_down': f.write(' self.OP.swipe_to_down()\n') # 向左滑动 elif ob.get_case_desc(i)[j][1] == 'swipe_to_left': f.write(' self.OP.swipe_to_left()\n') # 向右滑动 elif ob.get_case_desc(i)[j][1] == 'swipe_to_right': f.write(' self.OP.swipe_to_right()\n') # 判断页面内容是否存在 elif ob.get_case_desc(i)[j][1] == 'page_element': f.write(' self.OP.judge_key("%s", "%s", "%s")\n' % (ob.get_case_desc(i)[j][2], ob.get_case_desc(i)[j][3], ob.get_case_desc(i)[j][4])) elif ob.get_case_desc(i)[j][1] == 'set_keys': f.write(' self.OP.set_keys("%s", "%s", "%s")\n' % (ob.get_case_desc(i)[j][2], ob.get_case_desc(i)[j][3], ob.get_case_desc(i)[j][4])) elif ob.get_case_desc(i)[j][1] == 'shake': f.write(' self.OP.shake()\n') f.write(' except Exception as e:\n') f.write( ' creat_case.exception_handling(e, index=%s, test_name="%s", method_name=self.method_name,' ' op=self.OP)' % (ob.get_case_desc(i)[0], ob.get_case_desc(i)[1])) f.write('\n') try: f.close() except Exception as e: logging.error(e) raise Custom_exception.CloseFileError
def __init__(self): self.page = BastPage(Path.scan_files(prefix='page'))
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)