def generate_report(self): #给报告中添加执行环境信息 env_dict={} env=self.env.conf #修改把yaml格式改成对应的键值对 devices=env.get('devices') env.pop('devices') new_env=dict(env, **devices) env_dict.update(new_env) env_dict.update(self.conf.info) env_properties = {} for key0,value0 in env_dict.items(): for key,value in value0.items(): env_properties['{}.{}'.format(key0,key)]=str(value) try: with open( self.properties_path,'w',encoding='utf-8') as fp: jprops.store_properties(fp, env_properties) except: log.error('配置环境未输出到报告中') #执行生成报告命令 cmd = 'allure generate %s -o %s --clean' % (self.xml_report_path, self.html_report_path) try: Shell.invoke(cmd) log.info("测试报告成功生成") except: log.error("Html测试报告生成失败,确保已经安装了Allure-Commandline")
def find_ele_child_byelement(self, element_parent, locator_child, is_Multiple=False, wait=6): #通过父结点元素查找子结点元素,不支持name定位方式 if locator_child['type'] == 'name': log.error('find_ele_child_byelement的定位方式错误') raise NotFoundElementError value_child, type_child = locator_child['value'], locator_child['type'] try: WebDriverWait(self.driver, wait).until( lambda driver: element_parent.find_element(type_child, value_child)) log.info( "页面【{}】的元素【{}】成功查询到查找子节点 元素【{}】" .format(locator_child.get("page"), element_parent, locator_child.get('name'))) if is_Multiple == False: return element_parent.find_element(type_child, value_child) else: return element_parent.find_elements(type_child, value_child) except: log.info( "页面【{}】的元素【{}】未能查询到查找子节点 元素【{}】\n locator_child{}" .format(locator_child.get("page"), element_parent, locator_child.get('name'), locator_child)) if is_Multiple == False: return None else: return []
def _find_element(self, locator, is_need_displayed=True,wait = 5,is_raise=True): """查找单个元素,如果有多个返回第一个 Args: locator: 定位器 is_need_displayed: 是否需要定位的元素必须展示 is_raise: 是否抛出异常 Returns: 元素 ,没找到返回 None Raises: NotFoundElementError 未找到元素会抛 NotFoundElementError 异常 """ waittime_count=Waittime_count(msg='[查找] 页面【{}】该元素【{}】等待时间:'.format(locator.get("page"),locator.get("name"))) waittime_count.start() try: if is_need_displayed: WebDriverWait(self.driver, wait).until( lambda driver: self._get_element_by_type(driver, locator).is_displayed()) else: WebDriverWait(self.driver, wait).until( lambda driver: self._get_element_by_type(driver, locator) is not None) waittime_count.end() return self._get_element_by_type(self.driver, locator) except Exception as e: if is_raise==True: log.error( "【{}】页面中未能找到元素【{}】\n locator: \n {}".format(locator.get("page"), locator.get("name"), locator)) raise NotFoundElementError else: return None
def is_text_displayed(self, text, retry_time=0, is_raise=False): """检查页面中是否有文本关键字 如果希望检查失败的话,不再继续执行case,使用 is_raise = True Args: text: 关键字(请确保想要的检查的关键字唯一) is_retry: 是否重试,默认为true retry_time: 重试次数,默认为5 is_raise: 是否抛异常 Returns: True: 存在关键字 Raises: 如果is_raise = true,可能会抛NotFoundElementError """ try: if retry_time!=0: result= WebDriverWait(self.driver, retry_time).until( lambda driver: self._find_text_in_page(text)) else: result=self._find_text_in_page(text) if result == True: log.info("[Text]页面中找到了 %s 文本" % text) return result except TimeoutException: log.error("[Text]页面中未找到 %s 文本" % text) if is_raise: raise NotFoundTextError else: return False
def check_environment(self): log.info('检查环境...') # 判断是否设置环境变量ANDROID_HOME if "ANDROID_HOME" in os.environ: command = os.path.join(os.environ["ANDROID_HOME"], "platform-tools", "adb") else: raise EnvironmentError("Adb not found in $ANDROID_HOME path: %s." % os.environ["ANDROID_HOME"]) # 检查设备 current_devices = Device.get_android_devices() if len(current_devices) == 0: log.info('没有设备连接') exit() for device in self.devices: deviceName = device.get("deviceName") if deviceName in current_devices: log.info('已正常连接设备{}'.format(deviceName)) else: log.error('设备{}未正常连接'.format(deviceName)) # 检查appium版本 appium_v = Shell.invoke('appium -v') if self.appium.get("version") not in appium_v: log.info('appium 版本有问题') exit() else: log.info('appium version {}'.format(appium_v)) #检测appium-doctor输出 result = Shell.invoke('appium-doctor').splitlines() log.info(result)
def is_element_exist(self, locator,wait=2): """检查元素是否存在""" if self._find_element(locator,is_raise=False,wait=wait)==None: log.error("没有查找到 页面【{}】的元素【{}】".format(locator.get("page"),locator.get("name"))) return False else: log.info("已查找到 页面【{}】的元素【{}】".format(locator.get("page"),locator.get("name"))) return True
def tap(self,locator): #获取当前屏幕的分辨率,元素通过相对位置点击 """ :param locator: value格式为 "x,y" :return: """ if locator.get('type')!="tap": log.error('定位方式错误,不能通过坐标位置定位点击 \nlocator: {}'.format(str(locator))) else: position=locator.get('value').split(',') x=int(position[0])*self.width/1080 y=int(position[1])*self.height/1920 positions=[(x,y)] log.info("通过坐标({},{}), 成功点击 页面【{}】的元素【{}】".format(x,y,locator.get('page'),locator.get('name'))) self.driver.tap(positions,duration=400)
def _find_ele_child_byname(self, locator_parent, locator_child, is_Multiple=False, wait=8): #使用uiautomator通过父节点,定位子节点。 value_parent, type_parent = locator_parent['value'], locator_parent['type'] value_child, type_child = locator_child['value'], locator_child['type'] try: map = { "name": "textContains", "id": "resourceId", "class name": "className" } type_parent = map.get(type_parent) if type_parent == None: log.error('当前定位方式不支持') raise NotFoundElementError ui_value = 'new UiSelector().{}(\"{}\").childSelector(new UiSelector().textContains(\"{}\"))'.format( type_parent, value_parent, value_child) WebDriverWait(self.driver, wait).until( lambda driver: driver.find_element_by_android_uiautomator(ui_value)) log.info("页面【{}】的元素【{}】成功查找子节点 元素【{}】".format(locator_parent.get("page"), locator_parent.get("name"), locator_child.get('name'))) if is_Multiple == False: return self.driver.find_element_by_android_uiautomator(ui_value) else: return self.driver.find_elements_by_android_uiautomator(ui_value) except: log.info( "页面【{}】的元素【{}】未能查询到查找子节点 元素【{}】\n locator_parent:{} \n locator_child{}" .format(locator_parent.get("page"), locator_parent.get("name"), locator_child.get('name'), locator_parent, locator_child)) if is_Multiple == False: return None else: return []
def find_ele_fromparent(self,locator_tmp,locator_target,is_Multiple=False,wait=5): #通过uiautomator查找定位元素的兄弟节点元素,不支持xpath,且兄弟节点必须同级 """ 支持的定位方式有:text(name),description(特有的),id,class name """ log.info("页面【{}】通过元素【{}】查找兄弟元素【{}】".format(locator_tmp.get("page"), locator_tmp.get('name'), locator_target.get("name"))) map={ "name":"textContains", "description":"descriptionContains", "id":"resourceId", "class name":"className" } type_tmp=map.get(locator_tmp["type"]) type_target=map.get(locator_target["type"]) if type_tmp==None or type_target==None: log.error('当前定位方式不支持') raise NotFoundElementError value_tmp=locator_tmp["value"] value_target =locator_target["value"] ui_value='new UiSelector().{}(\"{}\").fromParent(new UiSelector().{}(\"{}\"))'.format(type_tmp,value_tmp,type_target,value_target) try: WebDriverWait(self.driver, wait).until( lambda driver: driver.find_element_by_android_uiautomator(ui_value)) if is_Multiple == False: return self.driver.find_element_by_android_uiautomator(ui_value) else: return self.driver.find_elements_by_android_uiautomator(ui_value) except: log.info('页面【{}】未找到 元素【{}】\n locator: {}'.format(locator_tmp.get("page"), locator_target.get('name'),str(locator_target))) if is_Multiple == False: return None else: return []
def find_ele_parent(self, locator_parent,locator_child,wait=2): # 通过子节点来定位父节点元素,locator_parent有多个元素(通过遍历父节点,找出包含符合条件子节点的父节点) #定位方式限制 子节点 定位方式不能是name if locator_child['type'] == 'name': log.error('find_ele_parent的定位方式错误') raise NotFoundElementError elelist_parent = self.find_ele(locator_parent, is_Multiple=True) for element_parent in elelist_parent: child_eles=self.find_ele_child_byelement(element_parent,locator_child,is_Multiple=True,wait=wait) log.info(child_eles) if child_eles!=[]: log.info("成功遍历查找到元素 {}".format(child_eles)) return element_parent log.info('未找到元素, elelist_parent:{}'.format(str(elelist_parent))) return None
def _find_elements(self, locator,wait = 6,is_raise=False): """查找元素,可查找出多个 Args: locator: 定位器 is_raise: 是否抛出异常 Returns:元素列表 或 [] """ try: WebDriverWait(self.driver, wait).until( lambda driver: self._get_element_by_type(driver, locator, False).__len__() > 0) return self._get_element_by_type(self.driver, locator, False) except: if is_raise == True: log.error( "【{}】页面中未能找到元素【{}】\n locator: \n {}".format(locator.get("page"), locator.get("name"), locator)) raise NotFoundElementError else: return []
def is_toast_show(self, message, wait=5): """Android检查是否有对应Toast显示,常用于断言 Args: message: Toast信息 wait: 等待时间 Returns: True 显示Toast """ toast_loc = ("xpath", ".//*[contains(@text,'%s')]" % message) try: WebDriverWait(self.driver, wait, 0.2).until(expected_conditions.presence_of_element_located(toast_loc)) log.info("当前页面成功找到toast: %s" % message) return True except : log.error("当前页面中未能找到toast为: %s" % message) return False