Python+Selenium+uniitest项目实战(一)
本项目是基于Python语言的前台自动化,使用的是Unittest框架(后续会优化Pytest框架)。PO模式,将测试对象(页面元素)与测试用例(元素操作+测试数据)进行分离。
项目包含以下几个部分:

Common:公共部分-对seleniumAPI的二次封装、日志输出、报错截图、读取yaml配置文件
configer :项目的配置信息
OutPuts:输出-日志、报告、截图
PageLocators:页面元素定位
PageObject:页面操作
TestCases:测试用例
TestData:测试数据
runner.py 主程序入口
BasePage.py
'''对selenium的基本api进行二次封装。添加日志/截图/异常处理功能。''' from datetime import datetime from selenium.webdriver.remote.webdriver import WebDriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from Common.loghandler import logger from web_test.configer.setting import Config class BasePage: # 通过driver: WebDriver指定为driver类型,这样有自动补全提示 def __init__(self, driver: WebDriver): self.driver = driver # 等待元素可见 def wait_ele_visible(self, page_name, loc, timeout=30, poll_fre=1): logger.info(f'等待{loc}元素可见') try: WebDriverWait(self.driver, timeout, poll_frequency=poll_fre).until(EC.visibility_of_element_located(loc)) except: self.save_page_shot(page_name) logger.error(f'等待{loc}元素可见失败,保存截图') raise # 查找元素 def find_ele(self, page_name, loc): logger.info(f'查找元素{loc}') try: ele = self.driver.find_element(*loc) except: self.save_page_shot(page_name) logger.error(f'查找元素{loc}失败') raise else: return ele # 查找元素组 def find_eles(self, page_name, loc): logger.info(f'查找所有元素{loc}') try: eles = self.driver.find_elements(*loc) except: self.save_page_shot(page_name) logger.error(f'查找元素{loc}失败') raise else: return eles # 点击元素 def click_ele(self, page_name, loc, timeout=10, poll_fre=1): logger.info(f'在{page_name}页面执行点击元素{loc}操作') self.wait_ele_visible(page_name, loc, timeout, poll_fre) ele = self.find_ele(page_name, loc) try: ele.click() except: self.save_page_shot(page_name) raise # 输入 def input_text(self, page_name, loc, value, timeout=10, poll_fre=1): logger.info(f'在{page_name}页面向元素{loc}执行输入操作') self.wait_ele_visible(page_name, loc, timeout, poll_fre) ele = self.find_ele(page_name, loc) try: ele.send_keys(value) except: logger.error('元素输入失败') self.save_page_shot(page_name) raise # 获取元素属性 def get_ele_attribute(self, page_name, loc, attr_name, timeout=10, poll_fre=1): logger.info(f'在{page_name}页面获取{loc}元素的属性{attr_name}') # self.wait_ele_visible(page_name, loc, timeout, poll_fre)--获取元素属性不一定要元素可见 ele = self.find_ele(page_name, loc) try: attribute = ele.get_attribute(attr_name) except: logger.error('获取元素属性失败') self.save_page_shot(page_name) raise else: logger.info(f'在{page_name}页面获取到{loc}元素的属性{attr_name}:{attribute}') return attribute # 获取文本 def get_ele_text(self, page_name, loc, timeout=10, poll_fre=1): logger.info(f'在{page_name}页面获取{loc}元素的文本') self.wait_ele_visible(page_name, loc, timeout, poll_fre) try: ele_text = self.find_ele(page_name, loc) except: logger.info('获取文本失败') self.save_page_shot(page_name) raise else: logger.info(f'在{page_name}页面获取到{loc}元素文本:{ele_text}') return ele_text # 保存失败页面截图 def save_page_shot(self, page_name): # 截图名称:路径 + 时间戳 + 图片描述 # 从配置文件中获取截图文件放置路径 filedir = Config.screenshot_path curr_time = datetime.now().strftime('%Y%m%d-%H%M%S') file_name = filedir + curr_time + page_name + '.png' self.driver.save_screenshot(file_name) logger.error(f'元素操作失败,截图{file_name}已保存')
loghandler.py
# encoding=utf8
'''封装日志处理'''
import datetime import logging import os from Common.yamlconfhandler import yaml_data from web_test.configer.setting import Config class LoggerHandle(logging.Logger): def __init__(self, filename=None, name='root', level='WARNING', format ='[%(asctime)s-%(name)s]-[%(filename)s-%(funcName)s-%(lineno)s]-[%(levelname)s]--%(message)s', ): super().__init__(name) self.setLevel(level) if filename: file_handler = logging.FileHandler(filename, mode='a', encoding='utf-8') file_handler.setLevel(level) fmt = logging.Formatter(format) file_handler.setFormatter(fmt) self.addHandler(file_handler) else: stream_handler = logging.StreamHandler() stream_handler.setLevel(level) fmt = logging.Formatter(format) stream_handler.setFormatter(fmt) self.addHandler(stream_handler) log_dir = Config.log_dir curr_date = datetime.datetime.now().strftime('%Y-%m-%d') logName = os.path.join(log_dir, curr_date + '.Logs') logger = LoggerHandle(filename=logName, name=yaml_data['logger']['name'], level=yaml_data['logger']['level']) if __name__ == '__main__': logger.warning('warning info-------------------------')
yamlconfhandler.py
# encoding=utf8 '''yaml读取配置文件方法''' import yaml from web_test.configer.setting import Config class YamlHandler: def __init__(self, file, encoding='utf8'): self.file = file self.encoding = encoding def yaml_read(self, key=None): with open(self.file, encoding=self.encoding)as f: data = yaml.load(f.read(), yaml.FullLoader) try: if key == None : return data else: return data[key] except: return '读取异常……' def yaml_write(self, message): with open(self.file, mode='w', encoding=self.encoding)as f: yaml.dump(message, stream=f, allow_unicode=True) yaml_data = YamlHandler(Config.yaml_conf_path).yaml_read() if __name__ == '__main__': print(yaml_data)

用来保存项目的配置信息
conf.yaml
logger: level: DEBUG name: root days: 7 database: database: xxxxx host:xxxxx password: 123456 port: 3306 user: xxxxx
setting.py
# encoding=utf8 import os class Config: # 获取到项目目录 root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) cur_path = os.path.dirname(os.path.abspath(__file__)) # yaml 配置文件路径 yaml_conf_path = os.path.join(cur_path, 'conf.yaml') # 获取到测试数据所在目录 data_path = os.path.join(root_path, r'data\test_data.xlsx') # 测试用例所在目录 testcase_path = os.path.join(root_path, 'testcases') # log日志所在目录 log_dir = os.path.join(root_path, r'Outputs\Logs') if not os.path.exists(log_dir): os.mkdir(log_dir) # report 测试报告所在目录 report_dir = os.path.join(root_path, r'Outputs\AllureReport') if not os.path.exists(report_dir): os.mkdir(report_dir) # 屏幕截图保存路径 screenshot_path = os.path.join(root_path, r'Outputs\ScreenShots\\') enviroment_file_path = os.path.join(cur_path, 'environment.properties') categories_file_path = os.path.join(cur_path, 'categories.json') base_url = 'http://xxxxxxxxx' login_url = base_url + '/Index/login.html' if __name__ == '__main__': print(Config.root_path) print(Config.screenshot_path)
别怕路长梦远👣,总有星河照耀✨,未来可期💖

浙公网安备 33010602011771号