一、实现数据与代码分离,维护成本较低,先看看自动化结构,大体如下:
-
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: 返回次数或者上滑次数
![](https://i-blog.csdnimg.cn/blog_migrate/5474b860da2b3cab8e402eebc6aaa074.jpeg)
代码部分
公共部分
个人觉得核心的就是公共部分,相当于建房子,公共部分搞好了,后面仅仅是调用即可,建房子把架子搭好,后面就添砖加瓦吧。
读取配置文件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文件
运行首页用例:
config.ini 文件里面放启动app的那五项目,platformversion和devicename 是动态回去然后存在里面的,以及发邮件的那些发件人,收件人,密码等
[config] platformname = Android apppackage = com.yuedan appactivity = com.yuedan.ui.Activity_Splash platformversion = 5.0.1 devicename = R8V5T15930002010 [cmd] openappium = node /Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js stopappium = pkill node startserver = adb statr-server closeserver = adb kill-server checkphone = adb get-state viewphone = adb devices viewandroid = adb shell grep ro.build.version.release /system/build.prop [email] smtpsever = smtp.qq.com user = 1075937080@qq.com password = nlyislfjmcvsibaa sender = 1075937080@qq.com receiverguolinli@iyuedan.com
运行所有用例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()