5. 继承基类实现浏览器_Edge

发布于:2025-05-01 ⋅ 阅读:(34) ⋅ 点赞:(0)

继承基类实现浏览器_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
  • 作用:执行浏览器类型安全校验
  • 关键技术
    • 使用TypeUnion进行类型注解
    • 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加载驱动
    • 应用无痕模式配置
    • 设置窗口最大化
    • 配置各类超时参数

类关系图示

«Abstract»
BROWSER
+ CHROME_DRIVER_PATH
+ EDGE_DRIVER_PATH
+ WINDOWS_SIZE
+ IMP_TIME
+ PAGE_LOAD_TIME
+ SCRIPT_TIME_OUT
+ HEADLESS
- _path
- _browser
- _option
+__init__()
+get_browser_options()
+start_browser()
CHROME
+ OPTION_MARK
+ METHOD_MARK
+ START_MAX
+ EXP
+get_chrome_options()
+start_chrome_browser()
EDGE
+get_edge_options()
+start_edge_browser()

关键设计特点

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)

“良好的基类设计是自动化框架的基石,决定了系统的扩展上限”


「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀


网站公告

今日签到

点亮在社区的每一天
去签到