当前位置:首页 > 技术 > 正文内容

Selenium结合Unittest实现UI自动化测试的分层架构设计

访客 技术 2026年7月26日 1
在构建可维护的UI自动化测试框架过程中,采用合理的代码分层结构至关重要。本文介绍一种基于Selenium与Unittest的四层架构模式,提升测试脚本的复用性与可读性。

项目结构概览

该架构包含四个核心层级:
  • Base层:封装浏览器底层操作
  • Page层:定义页面业务逻辑
  • Data层:管理测试数据
  • Case层:组织测试用例执行流程
四层架构示意图

Base层 - 浏览器操作抽象

此层提供通用UI交互方法,降低上层对Selenium原生API的依赖。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains

class ElementHandler:
    def __init__(self, driver):
        self.driver = driver
        self.wait = WebDriverWait(driver, 10)

    # 启动浏览器并访问URL
    def launch(self, address):
        self.driver.get(address)
        self.driver.maximize_window()

    # 定位元素
    def locate(self, method, locator):
        return self.driver.find_element(method, locator)

    # 元素点击
    def tap(self, method, locator):
        element = self.locate(method, locator)
        element.click()

    # 输入文本(自动清除只读属性)
    def type_text(self, method, locator, content):
        field = self.locate(method, locator)
        self.driver.execute_script("arguments[0].removeAttribute('readonly')", field)
        field.clear()
        field.send_keys(content)

    # 模拟键盘操作
    def press_key(self, method, locator, key):
        self.locate(method, locator).send_keys(key)

    # 双击操作
    def double_tap(self, method, locator):
        ActionChains(self.driver).double_click(
            self.locate(method, locator)
        ).perform()

    # 显式等待
    def pause(self, seconds):
        self.driver.implicitly_wait(seconds)

    # 切换至新标签页
    def switch_to_new_tab(self):
        self.driver.switch_to.new_window('tab')

    # 关闭浏览器
    def close_browser(self):
        self.driver.quit()

Page层 - 页面行为建模

将具体业务流程封装为类方法,提高用例编写效率。 LoginPage.py
from Base.core import ElementHandler
from selenium.webdriver.common.by import By

class LoginPage(ElementHandler):
    # 环境配置
    STAGING_URL = "https://test.kritycat.com"
    UAT_URL = "https://uat.kritycat.com"
    
    USERNAME = "admin"
    PASSWORD = "secret"

    def login_to_staging(self):
        self.launch(self.STAGING_URL)
        self._execute_login()

    def login_to_uat(self):
        self.launch(self.UAT_URL)
        self._execute_login()

    def _execute_login(self):
        self.type_text(By.ID, "user", self.USERNAME)
        self.type_text(By.ID, "password", self.PASSWORD)
        self.tap(By.ID, "login")
        self.pause(5)
FormPage.py
from Base.core import ElementHandler
from selenium.webdriver.common.by import By

class FormProcessor(ElementHandler):
    def fill_form_id(self, form_id):
        self.tap(By.ID, "Type")
        self.type_text(By.XPATH, '//*[@id="Type"]/div/div/input', form_id)

Data层 - 数据驱动支持

使用YAML文件存储测试参数,实现数据与逻辑分离。 form_data.yaml
- 
  form_id: "0001"

Case层 - 测试执行入口

通过unittest组织测试套件,并利用DDT实现数据驱动。
import unittest
from ddt import ddt, file_data
from selenium import webdriver
from Page.LoginPage import LoginPage
from Page.FormPage import FormProcessor

@ddt
class FunctionalTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.browser = webdriver.Chrome()
        cls.login_page = LoginPage(cls.browser)
        cls.form_task = FormProcessor(cls.browser)

    def test_login_process(self):
        self.login_page.login_to_staging()

    @file_data("../Data/form_data.yaml")
    def test_form_submission(self, form_id):
        self.form_task.fill_form_id(form_id)

    @classmethod
    def tearDownClass(cls):
        cls.browser.quit()

分层优势说明

  • 当登录地址变更时,仅需修改LoginPage中的常量值
  • 测试数据调整无需改动代码,只需更新对应YAML文件
  • 公共操作抽象后可在多个用例中重复调用
  • 各层职责清晰,便于团队协作与后期维护

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。