selenium自动化测试web自动化测试 框架封装Pom

python 复制代码
import os

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager

os.environ['WDM_LOCAL'] = '1'  # 强制使用本地缓存的驱动
os.environ['WDM_SKIP_UPDATE'] = '1'  # 跳过版本更新检查


class BasePage(object):
    def __init__(self):
        self.driver =  webdriver.Chrome(service=ChromeService(ChromeDriverManager().install())) #自动下载对应的驱动
    def get_url(self,url):
        self.driver.get(url)
    def quit_browser(self):
        self.driver.quit()

    def send_keys(self,selector,context):
        self.driver.find_element(*selector).send_keys(context)
    def click(self,selector):
        self.driver.find_element(*selector).click()
python 复制代码
from time import sleep

from selenium.webdriver.common.by import By
from day0320.pom.base.BasePage import BasePage

class LoginPage(BasePage):
    # 1.定义所有元素
    hc_username = (By.XPATH, "//*[@id='txtUName']")    #登录文本框
    hc_password = (By.XPATH, "//*[@id='txtPassword']")    #密码框
    hc_loginBtn = (By.XPATH, "//*[@id='btnLogin']")    #按钮
    hc_quit = (By.XPATH, "//*[@id='headerUserInfo']/span/a[2]")    #退出按钮

    #告诉代码 你在做什么
    def do_login(self, username, password):
        self.send_keys(self.hc_username,username)
        self.send_keys(self.hc_password,password)
        self.click(self.hc_loginBtn)


    def quit_login(self):
        self.click(self.hc_quit)

    # pom 本质把重复的操作独立的提取出去
    #页面的操作--它会有很多操作
    #页面操作都是固定的 元素会变 操作不会变
    #打开浏览器
    #关闭浏览器
    #输入文字
    #点击 (可以把所有的操作提取出去)
if __name__ == '__main__':
    lp = LoginPage()
    lp.get_url("http://novel.hctestedu.com/user/login.html")
    sleep(3)
    lp.do_login("13887310226","123456")
    sleep(5)
    lp.quit_browser()

一、POM(Page Object Model)框架核心思想

POM(页面对象模型)是 Selenium 自动化测试中最主流的框架设计模式,核心是:

  • 页面与逻辑分离:每个页面封装成一个类,包含页面元素定位和操作方法;
  • 复用性高:元素定位只写一次,修改时只需改一处;
  • 可读性强:测试用例只关注业务逻辑,不关注元素定位细节;
  • 易维护:页面结构变化时,只需修改对应页面类,不影响测试用例。

二、完整的 Selenium POM 框架封装(实战版)

以下是一套可直接复用的 POM 框架结构,包含基础封装、页面封装、测试用例三层架构:

python 复制代码
pom_project/
├── base/                  # 基础层:封装通用方法
│   ├── __init__.py
│   └── BasePage.py        # 封装驱动初始化、元素操作(点击/输入/等待等)
├── page/                  # 页面层:封装各页面的元素和操作
│   ├── __init__.py
│   ├── LoginPage.py       # 登录页
│   └── HomePage.py        # 首页(示例)
├── test_case/             # 测试用例层:编写具体测试逻辑
│   ├── __init__.py
│   └── test_login.py      # 登录测试用例
├── utils/                 # 工具层:封装辅助功能(可选)
│   ├── __init__.py
│   └── config.py          # 配置文件(如URL、账号密码)
└── run.py                 # 运行入口
1. 核心优势
  • 低耦合:页面元素 / 操作和测试用例分离,修改页面结构只需改对应 Page 类;
  • 高复用:多个用例可复用同一个 Page 类的方法(如登录操作);
  • 易扩展:新增页面时,只需新增一个 Page 类,继承 BasePage 即可;
  • 可读性强 :测试用例像自然语言,比如 login_page.login(phone, pwd) 一眼就能看懂。
2. 进阶拓展(可选)
  • 添加日志:在 BasePage 中封装日志打印,方便排查问题;
  • 数据驱动:结合 Excel/CSV/YAML 管理测试数据(如多组账号密码);
  • 测试报告:集成 pytest+allure 生成可视化测试报告;
  • 异常处理:在 BasePage 中添加通用异常捕获,比如元素定位失败时截图;
  • 多浏览器支持:在 BasePage 中添加 Chrome/Firefox/Edge 的驱动切换逻辑。

总结

  1. POM 核心:将页面元素、操作封装为 Page 类,测试用例只调用 Page 类的方法,实现 "页面与逻辑分离"。
  2. 框架结构:基础层(BasePage)→ 页面层(LoginPage/HomePage)→ 测试用例层(test_login),三层架构清晰易维护。
  3. 关键封装:BasePage 中封装通用操作(定位 / 点击 / 输入 / 等待),所有 Page 类继承它,避免重复代码。

这套框架可以直接适配你的自动化测试场景,只需替换config.py中的 URL、元素定位符,以及 Page 类中的业务逻辑即可。

复制代码
conftest 单独封装、流程化  都继承父类conftest
python 复制代码
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager

driver = None

@pytest.fixture(scope="session")
def browser():
    global driver
    if driver is None:
        driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))  # 自动下载对应的驱动
        driver.maximize_window()
    yield driver
    driver.quit()
python 复制代码
import os
import yaml

import pytest
from day0320.pom.page.LoginPage2 import LoginPage
from day0320.pom.page.BookDetilsPage import BookDetilsPage
from time import sleep
#经过了用例1-->用例2-->用例3#没有关闭浏览器,没有创建新的driver
curPath = os.path.dirname(os.path.realpath(__file__)) #获取当前脚本所在文件夹路径
ymlPath = os.path.join(curPath, "data.yaml") #获取yaml文件路径
f = open(ymlPath, "r")
d = yaml.safe_load(f.read())

@pytest.mark.parametrize("caseinfo",d["login"])
def test_01(browser,caseinfo):
    lp = LoginPage(browser)
    lp.get_url("http://novel.hctestedu.com/user/login.html")
    sleep(5)
    lp.do_login(caseinfo["username"],caseinfo["password"])
    sleep(3)
    lp.quit_login()

def test_02(browser):
    pass

def test_03(browser):
    db = BookDetilsPage(browser)
    db.get_url("http://novel.hctestedu.com/book/198.html")
    sleep(5)
    db.read_click()
    sleep(5)


if __name__ == '__main__':
    pytest.main(["-v","-s"])
相关推荐
2301_810160951 小时前
如何为开源Python项目做贡献?
jvm·数据库·python
weixin_457760002 小时前
基于pytorch实现LPR模型车牌识别
人工智能·pytorch·python·深度学习·lpr
Zaly.2 小时前
【Python刷题】LeetCode 3567 子矩阵的最小绝对差
python·leetcode·矩阵
Amumu121382 小时前
Js:内置对象
开发语言·前端·javascript
2501_945423542 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
广州华水科技2 小时前
2026年单北斗GNSS变形监测系统推荐,助力精准监控与智慧城市建设
前端
吃杠碰小鸡2 小时前
Python+Ai学习流程
人工智能·python·学习
飞Link2 小时前
具身智能音频处理核心框架 PyAudio 深度拆解与实战
开发语言·python·音视频
鸡吃丸子2 小时前
如何编写一个高质量的AI Skill
前端·ai