python+appium+yaml安卓UI自动化测试分享

一、实现数据与代码分离,维护成本较低,先看看自动化结构,大体如下:

  • testyaml管理用例,实现数据与代码分离,一个模块一个文件夹
  • public 存放公共文件,如读取配置文件、启动appium服务、读取Yaml文件、定义日志格式等
  • page 存放最小测试用例集,一个模块一个文件夹
  • results 存放测试报告及失败截图
  • testcase 存放测试用例
  • runtest.py 运行所有测试用例

运行的结果:

三、yaml格式介绍

  • element_info:定位元素信息
  • find_type:属性,id、xpath、text、ids
  • operate_type: click、wait_activity、send_keys、back、swipe_up、sleep、clickbox(有弹框就关闭,没有就跳过),check(经常预期结果),暂时就八种

    上面三个必填,operate_type必填!!!!!!

  • send_content:send_keys 时用到
  • index:ids时用到  (定位是复式的时候可以索引)
  • times: 返回次数或者上滑次数

代码部分

公共部分

个人觉得核心的就是公共部分,相当于建房子,公共部分搞好了,后面仅仅是调用即可,建房子把架子搭好,后面就添砖加瓦吧。

读取配置文件readconfig.py
设置日志格式logs.py
获取设备GetDevices.py
这几个通用的就不做介绍了

  • 读取yaml文件 GetYaml.py
  • #coding=utf-8
    #author=‘Shichao-Dong‘
    
    import sys
    reload(sys)
    sys.setdefaultencoding(‘utf8‘)  #设置编码格式
    import yaml
    import codecs
    import random
    from random import choice
    
    def rand( total, num):
        ‘‘‘生成不重复的随机数,total总数,num生成的个数‘‘‘
        li = [i for i in range(total)]
        res = []
        for i in range(num):
            t = random.randint(i, total - 1)
            res.append(li[t])
            li[t], li[i] = li[i], li[t]
        return res
    def random_phonenumber():
        # 生成随机手机号码
        area_num = 399999
        # area_number = choice(area_num)
        seed = "1234567890"
        sa = []
        for i in range(6):
            sa.append(choice(seed))
        last_eightnumber = ‘‘.join(sa)
        phone = str(area_num) + last_eightnumber
        return phone
    
    class getyaml:
        def __init__(self,path):
            self.path = path
    
        def getYaml(self):
            ‘‘‘
            读取yaml文件
            :param path: 文件路径
            :return:
            ‘‘‘
            try:
                f = open(self.path)
                data =yaml.load(f)
                f.close()
                return data
            except Exception:
                print(u"未找到yaml文件")
    
        def alldata(self):
            ‘‘‘
            获取yaml里面所有的数据
            :return:
            ‘‘‘
            data =self.getYaml()
            return data
    
        def caselen(self):
            ‘‘‘
            获取元素定位的个数
            :return:
            ‘‘‘
            data = self.alldata()
            length = len(data[‘testcase‘])
            return length
    
        def get_elementinfo(self,i):
            ‘‘‘
            获取yaml里面的element_info
            i:想要获取的索引
            :param i:
            :return:
            ‘‘‘
            data = self.alldata()
            # print data[‘testcase‘][i][‘element_info‘]
            return data[‘testcase‘][i][‘element_info‘]
    
        def get_findtype(self,i):
            ‘‘‘
           获取yaml里面的find_type
           i:想要获取的索引
           :param i:
           :return:
           ‘‘‘
            data = self.alldata()
            # print data[‘testcase‘][i][‘find_type‘]
            return data[‘testcase‘][i][‘find_type‘]
    
        def get_operate_type(self,i):
            ‘‘‘
           获取yaml里面的operate_type
           i:想要获取的索引
           :param i:
           :return:
           ‘‘‘
            data = self.alldata()
            # print data[‘testcase‘][i][‘operate_type‘]
            return data[‘testcase‘][i][‘operate_type‘]
    
        def get_index(self, i):
            ‘‘‘
              获取yaml里面的operate_type
              i:想要获取的索引
              :param i:
              :return:
              ‘‘‘
            data = self.alldata()
            if self.get_findtype(i) == ‘ids‘:
                 text_yaml = data[‘testcase‘][i][‘index‘]
                 if  str(text_yaml) == ‘listtext‘:
                     list_text = rand(10,5)
                     return list_text
                 elif str(text_yaml) == ‘random‘:
                     list_text = random.randint(1, 10)
                     return list_text
                 else:
                     return text_yaml
            if self.get_findtype(i) == ‘class_name‘:
                text_yaml = data[‘testcase‘][i][‘index‘]
                if str(text_yaml) == ‘listtext‘:
                    list_text = rand(10, 5)
                    return list_text
                elif str(text_yaml) == ‘random‘:
                    list_text = random.randint(1, 10)
                    return list_text
                else:
                    return text_yaml
            else:
                pass
    
        def get_send_content(self,i):
            ‘‘‘
             获取yaml里面的send_content
             i:想要获取的索引
             :param i:
             :return:
             ‘‘‘
            data = self.alldata()
            # print data[‘testcase‘][i][‘send_content‘]
            if self.get_operate_type(i) == ‘send_keys‘:
                 text_yaml  = data[‘testcase‘][i][‘send_content‘]
                 if str(text_yaml) == ‘phone_number‘:
                     text = random_phonenumber()
                     return str(text)
                 elif str(text_yaml) == ‘random‘:
                     text = random.randint(1, 10)
                     return text
                 else:
                    # text = text_yaml.decode(‘utf-8‘)
                    return str(text_yaml)
            else:
                pass
    
        def get_sleeptime(self, i):
            ‘‘‘
           获取yaml里面的operate_type
           i:想要获取的索引
           :param i:
           :return:
           ‘‘‘
            data = self.alldata()
            # print data[‘testcase‘][i][‘operate_type‘]
            return data[‘testcase‘][i][‘sleeptime‘]
    
        def get_backtimes(self, i):
            data =  self.alldata()
            if self.get_operate_type(i)==‘back‘ or self.get_operate_type(i)==‘swipe_up‘:
                return data[‘testcase‘][i][‘times‘]
            elif self.get_operate_type(i)==‘swipe_down‘:
                return data[‘testcase‘][i][‘times‘]
            elif self.get_operate_type(i)==‘swipe_left‘:
                return data[‘testcase‘][i][‘times‘]
            elif self.get_operate_type(i) == ‘swipe_right‘:
                return data[‘testcase‘][i][‘times‘]
            else:
                pass
    
        def get_title(self):
            data = self.alldata()
            # print data[‘testinfo‘][0][‘title‘]
            return  data[‘testinfo‘][0][‘title‘]
    
  • 启动appium服务 StartAppiumServer.py
    主要是启动appium并返回端口port,这个port在下面的driver中需要
  • #coding=utf-8
    #author=‘Shichao-Dong‘
    
    from logs import log
    import random,time
    import platform
    import os
    from GetDevices import devices
    
    log = log()
    dev = devices().get_deviceName()
    
    class Sp:
        def __init__(self, device):
            self.device = device
    
        def __start_driver(self, aport, bpport):
            """
           3. 多设备执行
            1. 安卓下多设备执行意味着每一个设备需要对应一个appium服务端,并且脚本部分需要实现多线程访问,appium服务端启动命令如下:
            appium -p 4490 -bp 3456 -U xxxx
            -p 表示服务端和脚本通信的端口
            -bp 表示服务端和设备的AppiumBootStrap.jar进行通信的端口
            -U 表示当前服务是针对哪一台设备的
            2. ios在xcode8以下不支持多设备执行原因是instruments不支持多实例
            """
            if platform.system() == ‘Windows‘:    #获取操作系统名称
                import subprocess
                subprocess.Popen("appium -p %s -bp %s -U %s" %(aport, bpport, self.device), shell=True)
    
        def start_appium(self):
            """
            启动appium
            p:appium port
            bp:bootstrap port
            :return: 返回appium端口参数
            """
            aport = random.randint(4700, 4900)
            bpport = random.randint(4700, 4900)
            self.__start_driver(aport, bpport)
    
            log.info( ‘start appium :p %s bp %s device:%s‘ %(aport, bpport, self.device))
            time.sleep(10)
            return aport
    
        def main(self):
            """
            :return: 启动appium
            """
            return self.start_appium()
    
        def stop_appium(self):
            ‘‘‘
            停止appium
            :return:
            ‘‘‘
            if platform.system() == ‘Windows‘:
                os.popen("taskkill /f /im node.exe")
    
    if __name__ == ‘__main__‘:
        s = Sp(dev)
        s.main()

    获取driver GetDriver.py
    platformName、deviceName、appPackage、appActivity这些卸载配置文件config.ini文件中,可以直接通过readconfig.py文件读取获得。
    appium_port有StartAppiumServer.py文件返回

  • #coding=utf-8
    #author=‘Shichao-Dong‘
    
    import time
    from appium import webdriver
    from selenium.common.exceptions import WebDriverException
    import readConfig
    import GetDevices
    from StartAppiumServer import Sp
    from logs import log
    import os
    
    log = log()
    conf = readConfig.Readconfig()
    
    platformName =conf.getConfigValue(‘platformName‘).encode(‘ascii‘)
    apppackage = conf.getConfigValue(‘appPackage‘).encode(‘ascii‘)
    appactivity = conf.getConfigValue(‘appactivity‘).encode(‘ascii‘)
    platformversion =conf.getConfigValue(‘platformversion‘).encode(‘ascii‘)
    devicename = conf.getConfigValue(‘devicename‘).encode(‘ascii‘)
    
    # s = Sp(devicename)
    # appium_port = s.main()   #启动appium
    
    def mydriver1():
        os.system(‘call adb shell input keyevent 82‘)
        desired_caps = {
                    ‘platformName‘:platformName,
                    ‘deviceName‘:devicename,
                    ‘platformVersion‘:platformversion,
                    ‘appPackage‘:apppackage,
                    ‘appActivity‘:appactivity,
                    ‘unicodeKeyboard‘:True,
                    ‘resetKeyboard‘:True,
                    # ‘noReset‘:True,
                    ‘newCommandTimeout‘:180
                    }
        try:
            driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub‘, desired_caps)
            # driver = webdriver.Remote(‘http://127.0.0.1:%s/wd/hub‘%appium_port,desired_caps)
            time.sleep(4)
            log.info(‘获取driver成功‘)
            return driver
        except WebDriverException:
            print ‘No driver‘
    
    def mydriver2():
        os.system(‘call adb shell input keyevent 82‘)
        desired_caps = {
                    ‘platformName‘:platformName,
                    ‘deviceName‘:devicename,
                    ‘platformVersion‘:platformversion,
                    ‘appPackage‘:apppackage,
                    ‘appActivity‘:appactivity,
                    ‘unicodeKeyboard‘:True,
                    ‘resetKeyboard‘:True,
                    ‘noReset‘:True,
                    ‘newCommandTimeout‘:180
                    }
        try:
            driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub‘, desired_caps)
            # driver = webdriver.Remote(‘http://127.0.0.1:%s/wd/hub‘%appium_port,desired_caps)
            time.sleep(4)
            log.info(‘获取driver成功‘)
            return driver
        except WebDriverException:
            print ‘No driver‘
  • BaseOperate.py 重新封装find等命令,里面主要是一些上滑、返回、find等一些基础操作
  • #coding=utf-8
    #author=‘Shichao-Dong‘
    
    from selenium.webdriver.support.ui import WebDriverWait
    from appium.webdriver.webelement import WebElement
    from selenium.webdriver.support import expected_conditions
    from selenium.webdriver.common.by import By
    from logs import log
    import os
    import time
    import random
    from random import choice
    from appium.webdriver.mobilecommand import MobileCommand
    
    ‘‘‘
    一些基础操作:滑动、截图、点击页面元素等
    ‘‘‘
    
    log = log()
    # driver = GetDriver.mydriver()
    
    class BaseOperate:
        def __init__(self,driver):
            self.driver = driver
    
        def back(self):
            ‘‘‘
            返回键
            :return:
            ‘‘‘
            os.popen("adb shell input keyevent 4")
    
        def get_window_size(self):
            ‘‘‘
            :return:返回屏幕的大小
            ‘‘‘
            x=self.driver.get_window_size()[‘width‘]
            y=self.driver.get_window_size()[‘height‘]
            return(x,y)
    
        def swipe_up(self):
            ‘‘‘
            :return:向上滑动
            ‘‘‘
            try:
                l=self.get_window_size()
                x1=int(l[0]*0.5)
                y1=int(l[0]*0.9)
                y2=int(l[1]*0.2)
                self.driver.swipe(x1,y1,x1,y2,1000)
            except:
                log.error(u"上滑动异常")
    
        def swipe_down(self):
            ‘‘‘
            :return:向下滑动
            ‘‘‘
            try:
                l=self.get_window_size()
                x1=int(l[0]*0.5)
                y1=int(l[0]*0.2)
                y2=int(l[1]*0.8)
                self.driver.swipe(x1,y1,x1,y2,1000)
            except:
                log.error(u"下滑动异常")
    
        def swipe_right(self):
            ‘‘‘
            :return:向右滑动
            ‘‘‘
            try:
                l=self.get_window_size()
                x1=int(l[0]*0.2)
                x2=int(l[0]*0.8)
                y1=int(l[1]*0.5)
                self.driver.swipe(x1,y1,x2,y1,1000)
            except:
                log.error(u"右滑动异常")
    
        def swipe_left(self):
            ‘‘‘
            :return:向左滑动
            ‘‘‘
            try:
                l=self.get_window_size()
                x1=int(l[0]*0.8)
                x2=int(l[0]*0.2)
                y1=int(l[1]*0.5)
                self.driver.swipe(x1,y1,x2,y1,1000)
            except:
                log.error(u"左滑动异常")
    
        def screenshot(self):
            now=time.strftime("%y%m%d-%H-%M-%S")
            PATH = lambda p: os.path.abspath(os.path.join(os.path.dirname(__file__), p))
            screenshoot_path = PATH(‘../results/screenshoot/failpic‘)
            self.driver.get_screenshot_as_file(screenshoot_path+now+‘.png‘)
    
        def find_id(self,id):
            ‘‘‘
            寻找元素
            :return:
            ‘‘‘
            # 判断元素是否显示
            try:
                self.driver.find_element_by_id(id).is_enabled()
                return True
            except :
                # self.screenshot()
                return False
    
        def find_name(self,name):
            ‘‘‘
            判断页面是否存在某个元素
            :param name: text
            :return:
            ‘‘‘
            findname = "//*[@text=‘%s‘]"%(name)
            try:
                self.driver.find_element_by_xpath(findname).is_enabled()
                return True
            except :
                # self.screenshot()
                return False
    
        def get_name(self,name):
            ‘‘‘
            定位页面text元素
            :param name:
            :return:
            ‘‘‘
            findname = "//*[@text=‘%s‘]"%(name)
            try:
                # element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(findname))
                WebDriverWait(self.driver, 15).until(lambda driver: driver.find_element_by_xpath(findname).is_displayed())
                element = self.driver.find_element_by_xpath(findname)
                return element
            except:
                # self.screenshot()
                log.error(‘未定位到元素:‘+‘%s‘%(name))
    
        def getname_text(self,name):
            ‘‘‘
            定位页面text元素
            :param name:
            :return:
            ‘‘‘
            findname = "//*[@text=‘%s‘]"%(name)
            try:
                # element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(findname))
                WebDriverWait(self.driver, 15).until(lambda driver: driver.find_element_by_xpath(findname).is_displayed())
                element_text = self.driver.find_element_by_xpath(findname).text
                return element_text
            except:
                # self.screenshot()
                log.error(‘未定位到元素:‘+‘%s‘%(name))
    
        def getid_text(self,id):
            ‘‘‘
            定位页面resouce-id元素文本
            :param id:
            :return:
            ‘‘‘
            try:
                # element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(xpath))
                WebDriverWait(self.driver, 20).until(lambda driver: driver.find_element_by_id(id).is_displayed())
                element_text = self.driver.find_element_by_id(id).text
                return element_text
            except:
                # self.screenshot()
                # self.driver.get_screenshot_as_file("D:/error.png")
                log.error(‘未定位到元素:‘+‘%s‘%(id))
    
        def getids_text(self,id):
            ‘‘‘
            定位页面resouce-id元素组
            :param id:
            :return:列表
            ‘‘‘
            try:
                elements = WebDriverWait(self.driver, 20).until(lambda x: x.find_elements_by_id(id))
                self.driver.implicitly_wait(2)
                return elements
            except:
                # self.screenshot()
                log.error(‘未定位到元素:‘+‘%s‘%(id))
    
        def get_id(self,id):
            ‘‘‘
            定位页面resouce-id元素
            :param id:
            :return:
            ‘‘‘
            try:
                # element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(xpath))
                WebDriverWait(self.driver, 20).until(lambda driver: driver.find_element_by_id(id).is_displayed())
                element = self.driver.find_element_by_id(id)
                return element
            except:
                # self.screenshot()
                # self.driver.get_screenshot_as_file("D:/error.png")
                log.error(‘未定位到元素:‘+‘%s‘%(id))
    
        def get_id_closebox(self, id):
            ‘‘‘
            专门关闭弹框的
            :param id:
            :return:
            ‘‘‘
            try:
                # elements = self.driver.find_elements_by_id(id)
                element = WebDriverWait(self.driver, 20).until(lambda x: x.find_element_by_id(id))
                self.driver.implicitly_wait(2)
                return element
            except:
                pass
    
        def get_text_closebox(self, name):
            ‘‘‘
            专门关闭弹框的
            :param :text
            :return:
            ‘‘‘
            findname = "//*[@text=‘%s‘]" % (name)
            try:
                # element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(xpath))
                WebDriverWait(self.driver, 20).until(lambda driver: driver.find_element_by_id(findname).is_displayed())
                element = self.driver.find_element_by_id(findname)
                return element
            except:
                pass
    
        def get_xpath(self,xpath):
            ‘‘‘
            定位页面xpath元素
            :param id:
            :return:
            ‘‘‘
            try:
                # element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(xpath))
                WebDriverWait(self.driver, 20).until(lambda driver: driver.find_element_by_xpath(xpath).is_displayed())
                element = self.driver.find_element_by_xpath(xpath)
                return element
            except:
                # self.screenshot()
                log.error(‘未定位到元素:‘+‘%s‘%(xpath))
    
        def get_classname(self, classname):
            ‘‘‘
            定位页面xpath元素
            :param id:
            :return:
            ‘‘‘
            try:
                elements = WebDriverWait(self.driver, 20).until(lambda x: x.find_elements_by_class_name(classname))
                self.driver.implicitly_wait(2)
                return elements
            except:
                # self.screenshot()
                log.error(‘未定位到元素:‘ + ‘%s‘ % (classname))
    
        def get_ids(self,id):
            ‘‘‘
            定位页面resouce-id元素组
            :param id:
            :return:列表
            ‘‘‘
            try:
                # elements = self.driver.find_elements_by_id(id)
                elements = WebDriverWait(self.driver, 20).until(lambda x: x.find_elements_by_id(id))
                self.driver.implicitly_wait(2)
                return elements
            except:
                # self.screenshot()
                log.error(‘未定位到元素:‘+‘%s‘%(id))
    
        def  get_webcss(self,css):
            ‘‘‘
                   定位约单的web页面
                   :param id:
                   :return:
            ‘‘‘
            try:
                self.driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {"name": "WEBVIEW_com.yuedan"})
                WebDriverWait(self.driver, 30).until(lambda driver: driver.find_element_by_css_selector(css).is_displayed())
                element = self.driver.find_element_by_css_selector(css)
                element.click()
                self.driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {"name": "NATIVE_APP"})
            except:
                # self.screenshot()
                # self.driver.get_screenshot_as_file("D:/error.png")
                log.error(‘未定位到元素:‘ + ‘%s‘ % (id))
    
        def  get_webcss_list(self,css,random):
            ‘‘‘
                   定位约单的web页面,
                   :param id:
                   :return:list
            ‘‘‘
            try:
                self.driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {"name": "WEBVIEW_com.yuedan"})
                elements = WebDriverWait(self.driver, 20).until(lambda x: x.find_elements_by_css_selector(css))
                elements[random].click()
                self.driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {"name": "NATIVE_APP"})
            except:
                # self.screenshot()
                # self.driver.get_screenshot_as_file("D:/error.png")
                log.error(‘未定位到元素:‘+‘%s‘%(id))
    
        def page(self):
            ‘‘‘
            返回至指定页面
            :return:
            ‘‘‘
            i=0
            while i<10:
                i=i+1
                findname = self.find_id(‘com.yuedan:id/th_home_page‘)
                if findname:
                    self.driver.find_element_by_id(‘com.yuedan:id/th_home_page‘).click()
                    self.driver.implicitly_wait(2)
                    break
                os.popen("adb shell input keyevent 4")
                istext = self.find_id("com.yuedan:id/bt_ok")
                if istext:
                    self.driver.find_element_by_id("com.yuedan:id/bt_ok").click()
    
        def rand(self,total, num):
            ‘‘‘生成不重复的随机数,total总数,num生成的个数‘‘‘
            li = [i for i in range(total)]
            res = []
            for i in range(num):
                t = random.randint(i, total - 1)
                res.append(li[t])
                li[t], li[i] = li[i], li[t]
            return res
    
        def random_phonenumber(self):
            # 生成随机手机号码
            area_num = 399999
            # area_number = choice(area_num)
            seed = "1234567890"
            sa = []
            for i in range(6):
                sa.append(choice(seed))
            last_eightnumber = ‘‘.join(sa)
            phone = str(area_num) + last_eightnumber
            return phone
  • Operate.py
  • 最关键的一步了,后面没有page都是调用这个文件进行测试,主要是根据读取的yaml文件,然后进行if...else...判断,根据对应的operate_type分别进行对应的click、sendkeys等操作
  • #coding=utf-8
    #author=‘Shichao-Dong‘
    
    from GetYaml import getyaml
    from BaseOperate import BaseOperate
    from logs import log
    import time
    
    log = log()
    
    class Operate:
        def __init__(self,path,driver):
            self.path = path
            self.driver = driver
            self.yaml = getyaml(self.path)
            self.baseoperate=BaseOperate(driver)
    
        def check_operate_type(self):
            ‘‘‘
            读取yaml信息并执行
            element_info:定位元素信息
            find_type:属性,id、xpath、text、ids
            operate_type: click、sendkeys、back、swipe_up 为back就是返回,暂时就三种
                        增加check  用于校验
            上面三个必填,operate_type必填!!!!!!
    
            send_content:send_keys 时用到
            index:ids时用到
            times:
            :return:
            ‘‘‘
    
            for i in range(self.yaml.caselen()):
                print(self.driver.current_activity)
                if self.yaml.get_operate_type(i) == ‘click‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    try:
                        if self.yaml.get_findtype(i) == ‘text‘:
                            self.baseoperate.get_name(self.yaml.get_elementinfo(i)).click()
                        elif self.yaml.get_findtype(i) == ‘id‘:
                            self.baseoperate.get_id(self.yaml.get_elementinfo(i)).click()
                        elif self.yaml.get_findtype(i) == ‘xpath‘:
                            self.baseoperate.get_xpath(self.yaml.get_elementinfo(i)).click()
                        elif self.yaml.get_findtype(i) == ‘class_name‘:
                            self.baseoperate.get_classname(self.yaml.get_elementinfo(i))[self.yaml.get_index(i)].click()
                        elif self.yaml.get_findtype(i) == ‘ids‘:
                            self.baseoperate.get_ids(self.yaml.get_elementinfo(i))[self.yaml.get_index(i)].click()
                    except:
                        self.baseoperate.page()
    
                elif self.yaml.get_operate_type(i) == ‘sleep‘:
                    time.sleep(self.yaml.get_sleeptime(i))
                elif self.yaml.get_operate_type(i) == ‘wait_activity‘:
                    self.driver.wait_activity(self.yaml.get_elementinfo(i), 30)
    
                elif self.yaml.get_operate_type(i) == ‘send_keys‘:
                    self.driver.implicitly_wait(5)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    try:
                        if self.yaml.get_findtype(i) == ‘text‘:
                            self.baseoperate.get_name(self.yaml.get_elementinfo(i)).send_keys(self.yaml.get_send_content(i))
                        elif self.yaml.get_findtype(i) == ‘id‘:
                            self.baseoperate.get_id(self.yaml.get_elementinfo(i)).send_keys(self.yaml.get_send_content(i))
                        elif self.yaml.get_findtype(i) == ‘xpath‘:
                            self.baseoperate.get_xpath(self.yaml.get_elementinfo(i)).send_keys(self.yaml.get_send_content(i))
                        elif self.yaml.get_findtype(i) == ‘ids‘:
                            self.baseoperate.get_ids(self.yaml.get_elementinfo(i))[self.yaml.get_index(i)].send_keys(
                                self.yaml.get_send_content(i))
                        elif self.yaml.get_findtype(i) == ‘idSpecial‘:
                            a = True
                            while a:
                                self.baseoperate.get_id(self.yaml.get_elementinfo(i)).send_keys(self.yaml.get_send_content(i))
                                self.driver.find_element_by_id(‘com.yuedan:id/tv_re_sent‘).click()
                                isreg = self.baseoperate.find_id(‘com.yuedan:id/message‘)
                                log.info(isreg)
                                if isreg:
                                    self.driver.find_element_by_id(‘com.yuedan:id/bt_ok‘).click()
                                else:
                                    a = False
                    except:
                        self.baseoperate.page()
    
                elif self.yaml.get_operate_type(i) == ‘cycleclick‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    try:
                        if self.yaml.get_findtype(i) == ‘ids‘:
                            yaml_text = self.yaml.get_index(i)
                            if isinstance(yaml_text,list):
                                for j in range(len(yaml_text)):
                                    self.baseoperate.get_ids(self.yaml.get_elementinfo(i))[j].click()
                            else:
                                self.baseoperate.get_ids(self.yaml.get_elementinfo(i))[self.yaml.get_index(i)].click()
                        else:
                            pass
                    except:
                        self.baseoperate.page()
    
                elif self.yaml.get_operate_type(i) == ‘webclick‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    try:
                        if self.yaml.get_findtype(i) == ‘css‘:
                            self.baseoperate.get_webcss(self.yaml.get_elementinfo(i))
                        elif self.yaml.get_findtype(i) == ‘ids‘:
                            self.baseoperate.get_webcss_list(self.yaml.get_elementinfo(i),self.yaml.get_index(i))
                    except:
                        self.baseoperate.page()
    
                elif self.yaml.get_operate_type(i) == ‘swipe_up‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    try:
                        for i in range(self.yaml.get_backtimes(i)):
                            self.baseoperate.swipe_up()
                    except:
                        self.baseoperate.page()
                elif self.yaml.get_operate_type(i) == ‘swipe_down‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    try:
                        for i in range(self.yaml.get_backtimes(i)):
                            self.baseoperate.swipe_down()
                    except:
                        self.baseoperate.page()
                elif self.yaml.get_operate_type(i) == ‘swipe_left‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    for i in range(self.yaml.get_backtimes(i)):
                        self.baseoperate.swipe_left()
                elif self.yaml.get_operate_type(i) == ‘swipe_right‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    for i in range(self.yaml.get_backtimes(i)):
                        self.baseoperate.swipe_right()
    
                elif  self.yaml.get_operate_type(i) == ‘clickbox‘:
                    self.driver.implicitly_wait(15)
                    self.driver.wait_activity(self.driver.current_activity, 15)
                    try:
                        if self.yaml.get_findtype(i) == ‘id‘:
                            isbox = self.baseoperate.find_id(self.yaml.get_elementinfo(i))
                            log.info("弹框%s"%isbox)
                            if isbox:
                                self.baseoperate.get_id_closebox(self.yaml.get_elementinfo(i)).click()
                        elif self.yaml.get_findtype(i) == ‘text‘:
                            isbox = self.baseoperate.find_name(self.yaml.get_elementinfo(i))
                            if isbox:
                                self.baseoperate.get_text_closebox(self.yaml.get_elementinfo(i)).click()
                    except:
                        self.baseoperate.page()
    
        def check_result(self):
            caselen =  self.yaml.caselen()
            if self.yaml.get_operate_type(caselen-1) == ‘check‘:
                self.driver.implicitly_wait(15)
                if self.yaml.get_findtype(caselen-1)  == ‘id‘:
                    result = self.baseoperate.find_id(self.yaml.get_elementinfo(caselen - 1))
                    return result
                elif self.yaml.get_findtype(caselen-1)  == ‘text‘:
                    result = self.baseoperate.getid_text(self.yaml.get_elementinfo(caselen - 1))
                    return result
                elif self.yaml.get_findtype(caselen-1)  == ‘ids‘:
                    result = self.baseoperate.getids_text(self.yaml.get_elementinfo(caselen - 1))[self.yaml.get_index(caselen-1)].text
                    return result
            else:
                pass
    
        def back_home(self):
            ‘‘‘
            返回首页
            :return:
            ‘‘‘
            self.baseoperate.page()
    
        def isloginapp(self):
            ‘‘‘判断是否登录成功‘‘‘
            log_eable = self.baseoperate.find_id(‘com.yuedan:id/login‘)  # 登录是否显示
            return log_eable
    

Page部分:是最小用例集,一个模块一个文件夹,以首页为例,首页写了4个用例,每个用例一个.py文件

运行首页用例:

运行所有用例runtest.py:

#coding=utf-8
#author=‘Shichao-Dong‘

import time,os
import unittest
import HTMLTestRunner
import smtplib
import datetime
from public.readConfig import Readconfig
from public.Sendemail import Email
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.header import Header
from email.mime.multipart import MIMEMultipart

from testcase.LoginTest import login
from testcase.HomeTest import home
from testcase.HostTest import host
from testcase.DemandTest import demand
from testcase.PersonalTest import personal
from testcase.ServiceTest import service

PATH = lambda p: os.path.abspath(os.path.join(os.path.dirname(__file__), p))

def testsuit():
    suite = unittest.TestSuite()
    suite.addTests([
                    unittest.defaultTestLoader.loadTestsFromTestCase(login),
                    unittest.defaultTestLoader.loadTestsFromTestCase(home),
                    unittest.defaultTestLoader.loadTestsFromTestCase(host),
                    unittest.defaultTestLoader.loadTestsFromTestCase(demand),
                    unittest.defaultTestLoader.loadTestsFromTestCase(personal),

])

    # runner = unittest.TextTestRunner(verbosity=2)
    # runner.run(suite)

    now=time.strftime("%y-%m-%d-%H-%M-%S")
    dirpath = PATH("./results/yuedan-")

    filename=dirpath + now +‘result.html‘
    fp=open(filename,‘wb‘)
    runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=‘约单自动化报告‘,description=u‘结果:‘)

    runner.run(suite)
    fp.close()

def send_email():
    #定义发件箱
    conf = Readconfig()
    smtpsever = conf.getemailValue(‘smtpsever‘)
    user = conf.getemailValue(‘user‘)
    password = conf.getemailValue(‘password‘)
    sender = conf.getemailValue(‘sender‘)
    receiver = conf.getemailValue(‘receiver‘)

    sendemail = Email()
    msg=sendemail.email()

    #发送邮件
    smtp=smtplib.SMTP()
    smtp.connect(smtpsever)
    smtp.login(user,password)
    smtp.sendmail(sender,receiver.split(‘,‘),msg.as_string())
    smtp.quit()
    print(u‘邮件发送成功‘)

if __name__ =="__main__":
    testsuit()
    # send_email()

原文地址:https://www.cnblogs.com/guo2733/p/10617422.html

时间: 2024-10-08 04:12:49

python+appium+yaml安卓UI自动化测试分享的相关文章

基于python语言下的UI自动化测试框架搭建(一)

pycharm工程展示 最近在搭一个UI自动化测试框架,想把整个搭建过程分享出来,如果有不对的地方,希望大家能够指正,首先创建一个名称为,antomation_framework_demo的工程文件, pycharm中工程及文件如下图所示: config:文件中包含调用的浏览器驱动及打开的URL地址 framework: 1.包含定义的页面基类,封装常用的页面操作方法 2.包含打开浏览器操作以及在相对路径下获取浏览器driver 3.日志处理方法 logs:执行日志以时间格式保存在该文件夹下,如

appium+python+unittest+HTMLRunner编写UI自动化测试集

简介 获取AppPackage和AppActivity 定位UI控件的工具 脚本结构 PageObject分层管理 HTMLTestRunner生成测试报告 启动appium server服务 以python文件模式执行脚本生成测试报告 下载与安装 下载需要自动化测试的App并安装到手机 获取AppPackage和AppActivity 参考:https://juejin.im/post/5c3809a451882524c84ebabe 最终,得到App的信息如下: 1 appPackage:c

App自动化(2)--Python&amp;Appium实现安卓手机九宫格解锁

九宫格作为常见的手势密码,我们在使用的时候,是从起点开始,按住不放,然后滑动手指,直到最后一个点松开手指,如果与设置的手势密码匹配,则解锁成功. 现在大多数九宫格作为一个元素存在,很难定位到每一个点. 解决思路有两个,一是用指针定位每一个点:二是先获取元素坐标位置,再获取元素大小,然后切割图片,分别计算出每个点的坐标: 本次笔记记录第一个解决思路: 目的:创建一个Unlock类,按顺序传入九宫格的解锁数字即可实现主屏幕解锁 模拟器:夜神 1.坐标定位到每个点 A.夜神模拟器开发者选项中开启指针位

基于python语言下的UI自动化测试框架搭建(二)

framework包中文件如下所示: base_page.py:常用操作方法 在framework包下创建base_page.py文件,文件中封装一些页面常用操作方法,可以自己在这个类中进行对应方法的添加,代码如下: 1 # coding=utf-8 2 import time 3 from selenium.common.exceptions import NoSuchElementException 4 import os.path 5 from framework.logger impor

关于去哪儿网的UI自动化测试脚本(Python实现)

UI自动化测试Qunar机票搜索场景访问Qunar机票首页http://flight.qunar.com,选择“单程”,输入出发.到达城市,选择today+7日后的日期,点“搜索”,跳转到机票单程搜索列表页.在列表页停留1分钟,至到页面上出现“搜索结束”.如果出现航班列表,对于出现“每段航班均需缴纳税费”的行随机点选“订票”按钮,在展开的列表中会出现“第一程”. “第二程”:对于没有出现“每段航班均需缴纳税费”的行随机点选“订票”按钮,在展开的列表底部中会出现“报价范围”如果不出现航班列表,则页

Python+Selenium搭建UI自动化测试框架

Python语言是非常强大的编程语言,很多时候也拿来当脚本语言用. Selenium是web应用测试工具,支持Java.Python等多种语言脚本,支持Chrome.Firefox等多种主流浏览器.主要实现的就是模拟人使用web应用,自动的打开浏览器.打开应用.进入应用进行各种模拟业务操作等等. 接下来,一步一步带领大家实现下Python+Selenium实现使用脚本自动发微博的功能. 1.Python安装 一般Linux系统自带了Python,Windows系统可以参考本人之前文章 [Pyth

基于python+appium通过图片对比来做的UI自动化

1.python + appium +图片对比实现UI自动化:背景:当手机需要适配不同的语言时,测试过程中易出现因为语言不熟悉,导致UIbug被遗漏(例如setting中的描述性文字显示不完整等等问题)环境搭建:需使用模块PIL,Windows版本链接地址:http://pythonware.com/products/pil/ubuntu (使用16.04虚拟机):sudo apt-get install python-imaging安装过程遭遇Unable to acquire the dpk

【腾讯TMQ】解放程序猿(媛)的双手—iOS UI自动化测试

解放程序猿(媛)的双手-iOS UI自动化测试 前言 随着移动互联网时代的蓬勃发展,移动终端的自动化测试也在业界日益活跃,总体来看在Android平台上的自动化工具和实践比较多,但是说到iOS平台无论从自动化工具的数量还是质量上就陡降了.究其原因,无外乎是iOS系统的封闭性,加上相对Android用户的数量少,导致对这个平台系统的自动化进展缓慢,据笔者了解到的情况,很多iOS平台的测试人员还处于纯手工测试模式,自动化程度和Android平台无法相论,更别提和PC端相比了. 然而越是困难的事,越是

软件测试培训 UI 自动化测试详解

软件测试培训小编有好久都没有跟新软件测试,从今天开始,小编会逐渐把这部分知识给大家补上!今天这篇文章给大家介绍的是: UI 自动化测试 互联网产品的迭代速度远高于传统软件,尤其是移动APP不但更新频繁,还需要在不同硬件.系统版本的环境下进行大量兼容测试,这就给传统测试方法和测试工具带来了巨大挑战.为满足产品敏捷开发.快速迭代的需求,自动化测试逐渐流行起来.自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程. 自动化测试的优点很多,简单罗列几条:避免重复工作.提高测试效率.保证每次测试地一