appium+python实战四:参数化和判断元素是否存在

判断元素是否存在

以下三种方法都可以判断元素是否存在:

    def is_element(self,source):
        page_source = self.driver.page_source
        if source in page_source:
            return True
        else:
            return False

    def is_element2(self,mode,located):
        if self.driver.find_elements(mode,located).__len__() >= 1:
            return True
        else:
            return False

    def is_element3(self,mode,located):
        global flag
        try:
            if mode == 'id':
                self.driver.find_element_by_id(located)
            elif mode == 'xpath':
                self.driver.find_element_by_xpath(located)
            elif mode == 'class':
                self.driver.find_element_by_class_name(located)
            elif mode == 'css':
                self.driver.find_element_by_css_selector(located)
            else:
                self.driver.find_element(mode,located)
            flag = True
        except NoSuchElementException:
            flag = False
        finally:
            return flag

1.获取当前界面的page_source,即界面元素,判断指定字符串是否存在,这个方法比较简单粗暴,但字符串的比较有局限性,比如换行符各种特殊字符。
2.find_elements用来查找元素并返回一个列表,如果列表为空的话说明当前界面不存在该元素,而find_element只是单纯做一个定位元素操作,如果元素不存在的话就会报错404。
3.利用try…expect…finally…实现定位不到元素时进行捕获异常,并置标记为False,表示没找到元素,就可以利用标记值进行下面的判断。如果定位到元素flag就置为True。NoSuchElementException是定位不到元素时需捕获的异常,避免程序报错终止。

另外,我们常常使用隐式等待和显式等待来增强查找元素的稳定性。而显式等待和隐式等待只是增加查询元素的次数,如果最终查找不到元素都是会报错的。在实际应用中,很多弹窗在特定情况下才会弹出,这里可以加多一层处理,如果元素存在且可视再执行下一个操作。在对其进行操作前先去判断该元素是否存在,加上显式等待对其进行轮询,避免查找一次后未搜索到元素使其退出的情况出现。
示例代码:

    def is_element_located(self,mode,located):
        def locat(driver):
            if self.driver.find_elements(mode,located).__len__() >= 1:
                return True
            else:
                return False
        try:
            WebDriverWait(self.driver,5).until(locat)
            return True
        except TimeoutException:
            return False

参数化

当一组测试用例有固定的测试数据时,可以通过参数化的方式简化测试用例的编写。pytest是可以支持参数化的,即@pytest.mark.parametrize。

情景:有个功能支持添加水印需求,水印颜色有四种,水印字号大小支持自定义,水印样式也支持选择,如果要遍历各种情况就可以使用参数化来实现,避免写过多的用例代码。

page类:

class WatermarkPage(BasePage):
    def choose_color(self,num):
        if num == 0:
            self.by_id("cn.wps.moffice_eng:id/watermark_color_0").click()
        elif num == 1:
            self.by_id("cn.wps.moffice_eng:id/watermark_color_1").click()
        elif num == 2:
            self.by_id("cn.wps.moffice_eng:id/watermark_color_2").click()
        elif num == 3:
            self.by_id("cn.wps.moffice_eng:id/watermark_color_3").click()
        else:
            Log.log().warning('所选颜色值需在1-4之间,超过则默认为第一个')

    def set_process(self,num):
        elemment = self.by_id("cn.wps.moffice_eng:id/watermark_textsize_progress")
        # 获取拖动条的宽
        width = elemment.size.get('width')
        #获取进度条坐标
        x = elemment.location.get('x')
        y = elemment.location.get('y')
        #精度需要自己调
        process = self.driver.swipe(x, y, int(width * num), y, 1000)
        Log.log().debug('水印字号大小为:%s' % process)

    def tag_tile(self):
        #is_selected()判断元素是否被选中
        if self.by_id("cn.wps.moffice_eng:id/watermark_spread_btn").is_selected():
            pass
        else:
            self.by_id("cn.wps.moffice_eng:id/watermark_spread_text").click()

    def choose_watermark(self,num):
        elsments = self.driver.find_elements_by_xpath('//android.widget.GridView//android.widget.FrameLayout')
        elsments[num].click()

用例实现:

	@pytest.mark.parametrize(
        "color,size,mark",[(0,0.4,1),(1,1,1),(2,0.8,0),(3,1.4,0),(2,0.1,2)]
    )
    def test_watermark_type_size(self,color,size,mark):
        self.page.choose_format(1)
        watermark_page = self.page.set_watermark()
        watermark_page.choose_color(color)
        watermark_page.set_process(size)
        watermark_page.choose_watermark(mark)
        watermark_page.tag_ok()
        self.page.tag_share_button().tag_save_album()

其中"color,size,mark"用来定义参数的名称,列表内的每一个元祖都是一条测试用例使用的测试数据,上述代码就表示一共会执行5个用例。ids默认是为None,用来定义测试用例的名称。

你可能感兴趣的:(UI自动化)