继承基类实现浏览器_Chrome
代码架构解析
1. 异常体系定义
class BrowserTypeError(Exception):
def __init__(self, _type):
self._type = _type
def __str__(self):
return f"Browser type {self._type} is not supported"
- 作用:自定义浏览器类型校验异常
- 功能:
- 继承Python标准Exception基类
- 存储引发异常的类型信息
- 重写__str__方法提供友好错误提示
- 触发场景:当传入不支持的浏览器类型时抛出
2. 基类BROWSER定义
2.1 类常量配置
class BROWSER:
CHROME_DRIVER_PATH = 'drivers/chrome_driver.exe'
EDGE_DRIVER_PATH = '../drivers/edge_driver.exe'
FIREFOX_DRIVER_PATH = '../drivers/gecko_driver.exe'
IE_DRIVER_PATH = '../drivers/IEDriverServer.exe'
WINDOWS_SIZE = (1024, 768)
IMP_TIME = 30
PAGE_LOAD_TIME = 20
SCRIPT_TIME_OUT = 20
HEADLESS = True
- 作用:统一管理浏览器配置参数
- 参数说明:
*_DRIVER_PATH
:各浏览器驱动路径WINDOWS_SIZE
:默认窗口尺寸*_TIME
:等待策略超时阈值HEADLESS
:无头模式开关
2.2 初始化方法
def __init__(self,
browser_type: Type[Union[Chrome, Firefox, Ie, Edge]] = Chrome,
option_type: Type[Union[ChromeOptions,...]] = ChromeOptions,
driver_path: str = CHROME_DRIVER_PATH):
# 类型校验
if not issubclass(browser_type, (Chrome, Firefox, Ie, Edge)):
raise BrowserTypeError(browser_type)
if not issubclass(option_type, (ChromeOptions,...)):
raise BrowserTypeError(option_type)
if not isinstance(driver_path, str):
raise TypeError
# 参数存储
self._path = driver_path
self._browser = browser_type
self._option = option_type
- 作用:执行浏览器类型安全校验
- 关键技术:
- 使用
Type
和Union
进行类型注解 issubclass
校验类继承关系isinstance
验证路径类型- 存储实例化参数
- 使用
2.3 抽象属性方法
@property
def option(self):
"""浏览器选项配置接口"""
return
@property
def browser(self):
"""浏览器实例生成接口"""
return
- 设计目的:
- 定义统一接口规范
- 强制子类实现具体逻辑
- 分离配置与实例化过程
3. CHROME子类实现
3.1 类常量覆盖
class CHROME(BROWSER):
IMP_TIME = 30
PAGE_LOAD_TIME = 30
SCRIPT_TIME_OUT = 30
WINDOWS_SIZE = (1920, 900)
HEADLESS = False
START_MAX = '--start-maximized'
EXP = {'excludeSwitches': ['enable-automation']}
- 作用:定制化Chrome参数
- 参数调整:
- 延长各类等待时间
- 设置更大窗口尺寸
- 关闭无头模式
- 添加窗口最大化参数
- 配置自动化开关排除项
3.2 选项配置实现
@property
def options(self):
chrome_option = self._option()
chrome_option.add_argument(self.START_MAX)
for k, v in self.EXP.items():
chrome_option.add_experimental_option(k, v)
chrome_option.headless = self.HEADLESS
return chrome_option
- 功能:
- 创建ChromeOptions实例
- 添加窗口最大化参数
- 设置实验性选项
- 控制无头模式状态
3.3 驱动实例化实现
@property
def browser(self):
chrome = self._browser(
service=Service(self._path),
options=self.options
)
chrome.implicitly_wait(self.IMP_TIME)
chrome.set_script_timeout(self.SCRIPT_TIME_OUT)
chrome.set_page_load_timeout(self.PAGE_LOAD_TIME)
return chrome
- 实现细节:
- 使用Service类管理驱动路径(Selenium 4+特性)
- 应用配置好的浏览器选项
- 设置隐式/显式等待参数
- 返回实例化后的浏览器对象
类关系图示
关键设计模式
1. 工厂方法模式
- 封装浏览器对象的创建过程
- 统一不同浏览器的实例化接口
2. 模板方法模式
- 基类定义算法框架
- 子类实现具体步骤
3. 策略模式
- 通过配置切换浏览器类型
- 运行时动态选择实现
代码特点总结
-
类型安全:
- 参数类型注解
- 运行时动态校验
- 严格继承关系控制
-
配置集中化:
- 路径统一管理
- 参数分类存储
- 常量与实现分离
-
扩展性设计:
- 通过继承支持新浏览器
- 预留标准扩展接口
- 支持参数动态覆盖
-
防御式编程:
- 参数合法性校验
- 异常精准捕获
- 错误快速失败
使用示例
with CHROME().browser as _chrome:
_chrome.get('http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx')
from time import sleep
sleep(3)
全部代码
"""
Python :3.13.3
Selenium: 4.31.0
"""
from selenium.webdriver import *
from selenium.webdriver.chrome.service import Service
from typing import Type, Union
class BrowserTypeError(Exception):
def __init__(self, _type):
self._type = _type
def __str__(self):
return f"Browser type {self._type} is not supported"
class BROWSER:
CHROME_DRIVER_PATH = 'drivers/chrome_driver.exe'
EDGE_DRIVER_PATH = '../drivers/edge_driver.exe'
FIREFOX_DRIVER_PATH = '../drivers/gecko_driver.exe'
IE_DRIVER_PATH = '../drivers/IEDriverServer.exe'
WINDOWS_SIZE = (1024, 768)
IMP_TIME = 30
PAGE_LOAD_TIME = 20
SCRIPT_TIME_OUT = 20
HEADLESS = True
def __init__(self,
browser_type: Type[Union[Chrome, Firefox, Ie, Edge]] = Chrome,
option_type: Type[Union[ChromeOptions, FirefoxOptions, IeOptions, EdgeOptions]] = ChromeOptions,
driver_path: str = CHROME_DRIVER_PATH):
# 类型校验
if not issubclass(browser_type, (Chrome, Firefox, Ie, Edge)):
raise BrowserTypeError(browser_type)
if not issubclass(option_type, (ChromeOptions, FirefoxOptions, IeOptions, EdgeOptions)):
raise BrowserTypeError(option_type)
if not isinstance(driver_path, str):
raise TypeError
# 实例参数存储
self._path = driver_path
self._browser = browser_type
self._option = option_type
@property
def option(self):
"""
浏览器特定的操作,在子类中实现
:return:
"""
return
@property
def browser(self):
"""
启动浏览器,返回浏览器实例
:return:
"""
return
class CHROME(BROWSER):
IMP_TIME = 30
PAGE_LOAD_TIME = 30
SCRIPT_TIME_OUT = 30
WINDOWS_SIZE = (1920, 900)
HEADLESS = False
START_MAX = '--start-maximized'
EXP = {
'excludeSwitches': ['enable-automation'],
#'mobileEmulation': {'deviceName': 'iPhone 6'}
}
@property
def options(self):
chrome_option = self._option()
chrome_option.add_argument(self.START_MAX)
for k, v in self.EXP.items():
chrome_option.add_experimental_option(k, v)
chrome_option.headless = self.HEADLESS
return chrome_option
@property
def browser(self):
# 使用 Service 传递驱动路径
chrome = self._browser(
service=Service(self._path),
options=self.options
)
chrome.implicitly_wait(self.IMP_TIME)
chrome.set_script_timeout(self.SCRIPT_TIME_OUT)
chrome.set_page_load_timeout(self.PAGE_LOAD_TIME)
# chrome.set_window_size(*self.WINDOWS_SIZE)
return chrome
with CHROME().browser as _chrome:
_chrome.get('http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx')
from time import sleep
sleep(3)
“优秀的基类设计是自动化测试框架成功的基石” —— 《Selenium高级编程》
「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀