一、设计思路
框架采用python3+yaml+po+unittest+HTMLTestRunner等技术编写的UI自动化测试框架
1.使用Page Object模式将页面定位和业务操作分开,分离测试对象(元素对象)和测试脚本(用例脚本),一个页面建一个对象类,提高用例的可维护性;
2.使用yaml管理页面空间元素和测试用例数据。例如一个页面元素发生变化时,不需要去修改代码,只需要在对应的页面元素yaml文件中修改即可。
3.以每个页面作为模块管理,随时组装,互不影响。
二、测试框架分层
1.框架层:基础组件封装,支撑整个框架的流程执行及功能扩展
2.用例层:根据用例场景构造test测试方法
3.业务层:封装页面对象类,一个页面建立一个类,业务层基础基础层page类
4.基础层:二次开发selenium的元素定位已经操作
三、编写用例方法
例如我需要新增百度搜索测试场景用例:
1.在testyaml目录下新增一个页面对象yaml文件,利用封装的yamlload方法将yaml文件中的dom元素读取出来,提供给封装页面对象类调用并定元素操作。
2.在testdata目录下新增一个yaml文件提供给用例测试数据
3.在page_obj目录编写百度搜索场景的页面对象类封装
4.在testcase目录编写测试用例文件,采用ddt数据驱动读取yaml测试数据源文件
5.通过多线程将驱动传给执行方法,并行开启多个浏览器执行测试
6.操作元素封装
7.浏览器驱动封装
from typing import Union, Type from selenium.webdriver import * from selenium.webdriver.opera.options import Options as OperaOptions from selenium.webdriver.edge.options import Options as EdgeOptions from setting import * BROWSERS = (Chrome, Ie, Firefox, Edge, Opera, PhantomJS) OPTIONS = (ChromeOptions, IeOptions, FirefoxOptions, EdgeOptions, OperaOptions) class BROWSER: CHROME_DRIVER_PATH = CHROME_DRIVER_PATH # 使用32位ie驱动解决文本输入缓慢的问题 IE_DRIVER_PATH = IE_DRIVER_PATH FIREFOX_DRIVER_PATH = FIREFOX_DRIVER_PATH EDGE_DRIVER_PATH = EDGE_DRIVER_PATH OPERA_DRIVER_PATH = OPERA_DRIVER_PATH HEADLESS = HEADLESS # IMPLICITLY WAITING TIME METHOD IMPLICITLY_WAIT_TIME = 10 # PAGE SOURCE LOAD TIME METHOD PAGE_LOAD_TIME = 10 # the script should wait during an # execute_async_script call before throwing an error SCRIPT_TIMEOUT = 0 # SET WINDOW SIZE METHOD WINDOWS_SIZE = (1024, 900) def __init__(self, browser_type: Type[Union[Chrome, Ie, Firefox, Edge, Opera, PhantomJS, Remote]] = Chrome, option_type: Type[Union[FirefoxOptions, ChromeOptions, IeOptions, EdgeOptions, OperaOptions]] = ChromeOptions, driver_path: str = CHROME_DRIVER_PATH): if not issubclass(browser_type, BROWSERS): raise TypeError if not issubclass(option_type, OPTIONS): raise TypeError if not isinstance(driver_path, str): raise TypeError self._driver = browser_type self._option = option_type self._path = driver_path @property def browser(self): """ subclass should implement this method return the instance of WebDriver :return: """ return @property def _options(self): """ subclass should implement this method return instance of the Option Type like ChromeOptions :return: """ return class CHROME(BROWSER): METHOD_MARK = True IMPLICITLY_WAIT_TIME = 30 PAGE_LOAD_TIME = 20 SCRIPT_TIMEOUT = 10 # HEADLESS MODEL OPTION HEADLESS = False OPTION_MARK = True # EXPERIMENTAL OPTION EXPERIMENTAL = { # 'mobileEmulation': {'deviceName': 'iPhone 6'}, #以移动格式现实启动页面做h5时候会用到 'excludeSwitches': ['enable-automation'] #浏览器启动时左上角提示正在运行自动化 } # WINDOW SIZE OPTION WINDOW_SIZE = '' # WINDOW_SIZE = '--window-size=1920,1080' # START MAXIMIZED OPTION START_MAXIMIZED = '--start-maximized' @property def _options(self): """ chrome浏览器特有的操作属性 :return: """ if self.OPTION_MARK: chrome_option = self._option() chrome_option.headless = self.HEADLESS if self.WINDOW_SIZE: chrome_option.add_argument(self.WINDOW_SIZE) if self.START_MAXIMIZED: # chrome_option.add_argument(self.START_MAXIMIZED) chrome_option.add_argument('--headless') chrome_option.add_argument('--disable-gpu') for k, v in self.EXPERIMENTAL.items(): chrome_option.add_experimental_option(k, v) return chrome_option return None @property def browser(self): """ 启动chrome浏览器并进行初始配置 :return: """ if self._options: chrome = self._driver(self._path, options=self._options) else: chrome = self._driver(self._path) if self.METHOD_MARK: chrome.implicitly_wait(self.IMPLICITLY_WAIT_TIME) chrome.set_page_load_timeout(self.PAGE_LOAD_TIME) chrome.set_script_timeout(self.SCRIPT_TIMEOUT) return chrome class IE(BROWSER): IMPLICITLY_WAIT_TIME = 20 PAGE_LOAD_TIME = 10 SCRIPT_TIMEOUT = 10 WINDOWS_SIZE = (1600, 1024) CLEAN_SESSION = True ATTACH_TIMEOUT = 10000 MARK = True def __init__(self): super(IE, self).__init__( browser_type=Ie, option_type=IeOptions, driver_path=super().IE_DRIVER_PATH ) @property def _options(self): """ ie浏览器特有的操作属性 :return: """ ie_option = self._option() ie_option.browser_attach_timeout = self.ATTACH_TIMEOUT ie_option.ensure_clean_session = self.CLEAN_SESSION return ie_option @property def browser(self): """ 启动ie浏览器并进行初始配置 :return: """ if self.MARK: ie = self._driver(self._path, options=self._options) else: ie = self._driver(self._path) ie.implicitly_wait(self.IMPLICITLY_WAIT_TIME) ie.set_page_load_timeout(self.PAGE_LOAD_TIME) ie.set_script_timeout(self.SCRIPT_TIMEOUT) ie.set_window_size(*self.WINDOWS_SIZE) return ie class FIREFOX(BROWSER): def __init__(self): super(FIREFOX, self).__init__( browser_type=Firefox, option_type=FirefoxOptions, driver_path=super().FIREFOX_DRIVER_PATH ) @property def _options(self): return def browser(self): return self._driver(self._path) class OPERA(BROWSER): def __init__(self): super(OPERA, self).__init__( browser_type=Opera, option_type=OperaOptions, driver_path=super().OPERA_DRIVER_PATH ) @property def _options(self): return def browser(self): return self._driver(self._path)
作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:程序员二黑】自提!