继承基类实现浏览器_Edge
代码架构解析
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'
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, Edge]] = Chrome,
option_type: Type[Union[ChromeOptions,...]] = ChromeOptions,
driver_path: str = CHROME_DRIVER_PATH):
# 类型校验
if not issubclass(browser_type, (Chrome, Firefox, 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 get_browser_options(self):
"""浏览器选项配置接口"""
return
@property
def start_browser(self):
"""浏览器实例生成接口"""
return
- 设计目的:
- 定义统一接口规范
- 强制子类实现具体逻辑
- 分离配置与实例化过程
3. CHROME子类实现
3.1 类常量覆盖
class CHROME(BROWSER):
OPTION_MARK = True
METHOD_MARK = True
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']}
- 参数调整:
OPTION_MARK
:选项生成开关METHOD_MARK
:方法应用开关- 延长各类等待时间
- 设置更大窗口尺寸
- 关闭无头模式
3.2 选项配置实现
@property
def get_chrome_options(self):
if self.OPTION_MARK:
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
return None
- 功能:
- 根据开关生成配置选项
- 添加窗口最大化参数
- 排除自动化提示开关
- 控制无头模式状态
3.3 驱动实例化
@property
def start_chrome_browser(self):
if self.get_chrome_options:
chrome = self._browser(
service=Service(self._path),
options=self.get_chrome_options
)
else:
chrome = self._browser(service=Service(self._path))
if self.METHOD_MARK:
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类管理驱动路径
- 根据方法开关应用等待策略
4. EDGE子类实现
4.1 初始化定制
class EDGE(BROWSER):
def __init__(self):
super().__init__(
browser_type=Edge,
option_type=EdgeOptions,
driver_path=super().EDGE_DRIVER_PATH
)
- 作用:显式指定Edge相关参数
- 特性:
- 继承父类构造方法
- 固定浏览器类型为Edge
- 使用专用EdgeService
4.2 选项配置
@property
def get_edge_options(self):
edge_option = self._option()
edge_option.add_argument("--incognito")
return edge_option
- 功能:
- 创建EdgeOptions实例
- 添加无痕模式参数
- 返回配置好的选项对象
4.3 驱动实例化
@property
def start_edge_browser(self):
edge = self._browser(
service=EdgeService(self._path),
options=self.get_edge_options
)
edge.implicitly_wait(self.IMP_TIME)
edge.set_page_load_timeout(self.PAGE_LOAD_TIME)
edge.set_script_timeout(self.SCRIPT_TIME_OUT)
edge.maximize_window()
return edge
- 实现细节:
- 使用EdgeService加载驱动
- 应用无痕模式配置
- 设置窗口最大化
- 配置各类超时参数
类关系图示
关键设计特点
1. 多态性设计
- 统一基类接口
- 差异化子类实现
- 运行时动态绑定
2. 防御式编程
- 三级类型校验体系
- 参数合法性检查
- 异常快速失败机制
3. 配置策略分离
- 选项生成与实例化解耦
- 开关控制功能模块
- 参数集中化管理
4. 扩展性架构
- 开放继承体系
- 低耦合模块设计
- 支持热插拔浏览器类型
使用示例
# Chrome浏览器实例化
chrome = CHROME().start_chrome_browser
# Edge浏览器实例化
edge = EDGE().start_edge_browser
全部代码
"""
Python :3.13.3
Selenium: 4.31.0
"""
from selenium.webdriver import *
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.edge.service import Service as EdgeService
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'
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, Edge]] = Chrome,
option_type: Type[Union[ChromeOptions, FirefoxOptions, EdgeOptions]] = ChromeOptions,
driver_path: str = CHROME_DRIVER_PATH):
# 类型校验
if not issubclass(browser_type, (Chrome, Firefox, Edge)):
raise BrowserTypeError(browser_type)
if not issubclass(option_type, (ChromeOptions, FirefoxOptions, 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 get_browser_options(self):
"""
浏览器特定的操作,在子类中实现
:return:
"""
return
@property
def start_browser(self):
"""
启动浏览器,返回浏览器实例
:return:
"""
return
class CHROME(BROWSER):
OPTION_MARK = True
METHOD_MARK = True
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 get_chrome_options(self):
if self.OPTION_MARK:
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
return None
@property
def start_chrome_browser(self):
if self.get_chrome_options:
# 使用 Service 传递驱动路径
chrome = self._browser(
service=Service(self._path),
options=self.get_chrome_options
)
else:
chrome = self._browser(service=Service(self._path))
if self.METHOD_MARK:
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().start_chrome_browser as _chrome:
# _chrome.get('http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx')
# from time import sleep
#
# sleep(3)
class EDGE(BROWSER):
def __init__(self):
super().__init__(
browser_type=Edge,
option_type=EdgeOptions,
driver_path=super().EDGE_DRIVER_PATH
)
@property
def get_edge_options(self):
edge_option = self._option()
# 添加清理缓存的参数
edge_option.add_argument("--incognito")
return edge_option
@property
def start_edge_browser(self):
edge = self._browser(
service=EdgeService(self._path),
options=self.get_edge_options
)
edge.implicitly_wait(self.IMP_TIME)
edge.set_page_load_timeout(self.PAGE_LOAD_TIME)
edge.set_script_timeout(self.SCRIPT_TIME_OUT)
edge.maximize_window()
return edge
with EDGE().start_edge_browser as _edge:
_edge.get('http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx')
from time import sleep
sleep(3)
“良好的基类设计是自动化框架的基石,决定了系统的扩展上限”
「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀