简单介绍下:
为了减少基本功能点点的测试,因此考虑到重复性劳动的不便利,因此我就打算用ui自动化的方式来解决
在冒烟测试的阶段,有很多是之前的功能,迭代版本并没有改动,但为了防止代码之间的相互影响,最好之前的流程最好也要测一遍
因此就有了UI自动化
为了更好的管理测试用例,我这里用的是Excel
总结一下涉及到的模块:
Common:公共模块(日志类,浏览器驱动配置项,关键字驱动)
Data:存放excel数据(用例数据)
Log:存放生成日志文件
Testcase:封装了关键字驱动Excel数据类
Email:存放发送邮件模块
关键字驱动类:(主要封装了selenium中的各种操作方法)
from time import sleep from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.support.select import Select from selenium.webdriver.support.wait import WebDriverWait from UiProject.Common.Options import Options def open_browser(type_): '''基于反射机制简化代码''' try: driver = getattr(webdriver,type_)(options=Options().option_conf()) except Exception as e: print(e) driver = webdriver.Chrome(options=Options().option_conf()) return driver class WebKey: '''初始化driver对象''' def __init__(self,type_): self.driver = open_browser(type_) self.driver.implicitly_wait(8) # 访问地址url def get(self,txt): self.driver.get(txt) # 关闭浏览器,释放资源 def quit(self): self.driver.quit() # 关闭游标 def close(self): self.driver.close() # 定位元素 def locator(self,name,value): return self.driver.find_element(name,value) # 点击操作 def click(self,name,value): self.locator(name,value).click() # 输入操作(输入内容可以是文本,也可以是路径) def input(self,name,value,txt): self.locator(name,value).send_keys(txt) # 通过js执行器获得文本信息,然后进行断言 def assert_not_in_text(self,name,value,variable,txt): try: content =self.js_handler(name,value,variable) assert txt not in content,'断言失败' return True except Exception as e: print(e) return False # 文本断言 def assert_text(self,name,value,txt): try: text =self.locator(name,value).text assert text==txt return True except Exception as e: return False # 切换窗口 def switch_window(self): handles = self.driver.window_handles self.driver.switch_to.window(handles[1]) # 切换iframe def switch_frame(self,name,value): if name=='id': self.driver.switch_to.frame(value) element = self.locator(name,value) self.driver.switch_to.frame(element) # 退出iframe def quit_iframe(self): self.driver.switch_to.default_content() # 强制等待 def sleep(self,txt): sleep(txt) # 显示等待 def wait(self,name,value): return WebDriverWait(self.driver,8,0.5).until(lambda el:self.locator(name,value),message="等待失败") # 鼠标悬停操作 def hover(self,name,value): element = self.locator(name,value) # 创建Action对象 actions = ActionChains(self.driver) actions.move_to_element(element) # 处理弹窗 # 切换到弹窗 '''确认弹窗''' def accept_alert(self): self.driver.switch_to.alert.accept() # 取消弹窗 def dismiss_alert(self): self.driver.switch_to.alert.dismiss() # 获取弹窗文本 def get_alerttext(self): return self.driver.switch_to.alert.text # prompt弹窗输入内容 def alert_input(self,text): return self.driver.switch_to.alert.send_keys(text) # Select下拉菜单选项 def select_index(self,name,value,index): # 先定位下拉菜单位置 el = Select(self.driver.find_element(name,value)) # 按下拉菜单的位置选择,从0开始 el.select_by_index(index) def select_value(self,name,value,option_text): # 先定位下拉菜单位置 el = Select(self.driver.find_element(name,value)) ##按下拉菜单的内容选择,页面中option标签的值 el.select_by_value(option_text) def select_visible_text(self,name,value,text): # 先定位下拉菜单位置 el = Select(self.driver.find_element(name, value)) #按下来菜单的显示文本内容选择 el.select_by_visible_text(text) # js执行器 def js_handler(self,name,value,variable): elment =self.locator(name,value) text =self.driver.execute_script(variable,elment) return text
ChromeOptions谷歌浏览器驱动配置项
''' 封装Chrome的配置类 ''' # ChromeOption类的封装 from selenium import webdriver class Options: def option_conf(self): '''配置Chrome配置项''' options = webdriver.ChromeOptions() # 默认启动窗体最大化 options.add_argument('start-maximized') # 去掉自动化提示条 options.add_experimental_option('excludeSwitches',['enable-automation']) # 添加本地缓存 # options.add_argument(r'--user-data-dir=C:\Users\15414\AppData\Local\Google\Chrome\User Data') # 添加无头指令 # options.add_argument('--headless') # 添加去掉密码弹窗管理 prefs = {} prefs["credentials_enable_service"] = False prefs["profile.password_manager_enabled"] = False options.add_experimental_option("prefs", prefs) # 开始无痕模式 options.add_argument('incognito') # 指定窗口大小 # options.add_argument('window-size=8000,3000') # 默认浏览器启动的位置 # options.add_argument('window-position=200,400') return options
Excel数据驱动(暂时还没有封装)
''' 进行excel数据驱动,excel数据驱动类底层代码 ''' import openpyxl from openpyxl.styles import PatternFill,Font,colors,Alignment from UiProject.Common.Log import Log from UiProject.Common.WebKey import WebKey logger = Log().Setlog() # 读取excel logger.info('正在读取Excel文件') excel = openpyxl.load_workbook('../Data/excel_data/testcase03.xlsx') # 获取sheet页 sheets = excel.sheetnames # 遍历sheet页 for sheet in sheets: logger.info('正在读取表格{0}'.format(sheet)) sheet_temp = excel[sheet] # 判断该表格是否为测试用例:根据表格sheet名是否含有testcase if 'testcase' in sheet: logger.info('正在执行{}'.format(sheet_temp['A1'].value)) # 遍历sheet页单元格 for values in sheet_temp.values: # 判断用例是否已经执行过,有执行结果的代表,用例已经执行过了 if 'Pass' or 'Fail' not in values[8]: # 读取用例执行部分内容 if type(values[0]) is int: logger.info('操作描述:{}'.format(values[6])) # print(values) # 定义字典 data = {} # 元素定位方法 data['name']=values[2] # 元素定位路径 data['value']=values[3] # 元素变量 data['variable']=values[4] # 输入的文本值 data['txt']=values[5] # print(data) # 优化数据,删除为None的数据 for key in list(data.keys()): if data[key] is None: del data[key] # print(data) # 调用关键字执行不同操作 if values[1]=='open_browser': wt = WebKey(values[5]) # 如果是断言,需要写入,判断断言是否成功,成功True,失败False elif 'assert' in values[1]: # 断言函数有返回 status =getattr(wt,values[1])(**data) if status: sheet_temp.cell(row=values[0] +2,column=8).value ='Pass' # sheet_temp.cell(row=values[0] +2, column=8).fill = PatternFill("solid", fgColor="#00FA9A") sheet_temp.cell(row=values[0] +2, column=8).font =Font(color=colors.BLUE,bold=True) sheet_temp.cell(row=values[0] +2, column=8).alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) else: sheet_temp.cell(row=values[0] +2,column=8).value ='Fail' # sheet_temp.cell(row=values[0] +2,column=8).fill = PatternFill("solid", fgColor="#FF0000") sheet_temp.cell(row=values[0] +2, column=8).font = Font(color='#A52A2A',bold=True) sheet_temp.cell(row=values[0] +2, column=8).alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) else: getattr(wt,values[1])(**data) else: break else: logger.info('该表格内容不是测试用例') # 写入后进行保存 logger.info('自动化用例执行完毕') excel.save('../Data/excel_data/testcase03.xlsx')
说下编写excel的测试用例的规则:
一个excel文件里可以包含多个sheet,可以都是测试用例,不是用例的话,程序不会执行
按照执行顺序,从sheet1开始执行
用例命名规范:必须包含testcase,如(testcase_01)
有断言的话,和预期结果不一致会执行失败,执行结果会为Fail,执行成功,执行结果为Pass
只有按照规则写测试用例,就可以自动执行几百条,几千条。