POM思想的理解与示例
目录
POM(Page Object Model)核心理解
一、POM 的核心原则
二、完整示例(python + pytest)
1、项目结构
2、基础页面类(封装action等
3、登录页面类(login_page.py)
4、主页类(dashboard_page.py)
5、pytest夹具配置(confest.py)
6、测试用例
三、POM 的优势
总结
POM(Page Object Model)核心理解
POM(页面对象模型) 是自动化测试中广泛使用的设计模式,它将页面元素定位和操作逻辑封装成独立的类,使测试脚本更易维护、复用和协作。
以下是其核心思想和实现示例:
一、POM 的核心原则
-
分离元素定位与测试逻辑
-
元素选择器(如
#username
)只存在于 Page 类中,测试脚本只调用方法(如login()
)。
-
-
一个页面一个类
-
每个页面(如登录页、主页)对应一个独立的类。
-
-
方法代表用户操作
-
如
clickSubmitButton()
而非直接写page.click('button')
。
-
-
返回其他 Page 对象
-
操作后返回新页面对象(如登录后返回主页对象)。
-
二、完整示例(python + pytest)
1、项目结构
tests/
├── features/
│ ├── login.feature # Gherkin 场景(与JS版相同)
│ └── steps/
│ └── login_steps.py # 步骤定义(Python实现)
├── pages/
│ ├── base_page.py # 基础页面类
│ ├── login_page.py # 登录页
│ └── dashboard_page.py # 主页
├── conftest.py # pytest 夹具配置
└── requirements.txt # 依赖文件
2、基础页面类(封装action等
# pages/base_page.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECclass BasePage:def __init__(self, driver):self.driver = driverself.wait = WebDriverWait(driver, 10) # 显式等待def click(self, locator):"""通用点击方法"""self.wait.until(EC.element_to_be_clickable(locator)).click()def type(self, locator, text):"""通用输入方法"""self.wait.until(EC.visibility_of_element_located(locator)).send_keys(text)def navigate_to(self, url):"""导航到指定URL"""self.driver.get(url)self.wait.until(lambda d: d.execute_script("return document.readyState") == "complete")
3、登录页面类(login_page.py)
# pages/login_page.py
from pages.base_page import BasePage
from selenium.webdriver.common.by import Byclass LoginPage(BasePage):# 元素定位器(元组形式,兼容By类)USERNAME_INPUT = (By.ID, "username")PASSWORD_INPUT = (By.CSS_SELECTOR, "#password")LOGIN_BUTTON = (By.XPATH, "//button[@type='submit']")ERROR_MESSAGE = (By.CLASS_NAME, "error-message")def enter_username(self, username):self.type(self.USERNAME_INPUT, username)return self # 支持链式调用def enter_password(self, password):self.type(self.PASSWORD_INPUT, password)return selfdef click_login(self):self.click(self.LOGIN_BUTTON)from pages.dashboard_page import DashboardPage # 延迟导入避免循环依赖return DashboardPage(self.driver) # 返回新页面对象def get_error_message(self):return self.wait.until(EC.visibility_of_element_located(self.ERROR_MESSAGE)).text# 完整登录流程def login(self, username, password):return (self.enter_username(username).enter_password(password).click_login())
4、主页类(dashboard_page.py)
# pages/dashboard_page.py
from pages.base_page import BasePage
from selenium.webdriver.common.by import Byclass DashboardPage(BasePage):WELCOME_MESSAGE = (By.CSS_SELECTOR, ".welcome-text")LOGOUT_BUTTON = (By.ID, "logout-btn")def get_welcome_message(self):return self.wait.until(EC.visibility_of_element_located(self.WELCOME_MESSAGE)).textdef click_logout(self):self.click(self.LOGOUT_BUTTON)from pages.login_page import LoginPage # 延迟导入return LoginPage(self.driver)
5、pytest夹具配置(confest.py)
# conftest.py
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options@pytest.fixture(scope="module")
def driver():"""共享浏览器实例"""options = Options()options.headless = True # 无头模式driver = webdriver.Chrome(options=options)yield driverdriver.quit() # 测试结束后关闭浏览器@pytest.fixture
def login_page(driver):"""登录页夹具"""from pages.login_page import LoginPagereturn LoginPage(driver)
6、测试用例
# tests/test_login.py
def test_successful_login(login_page):dashboard_page = login_page.login("admin", "admin123")assert "Welcome, admin" in dashboard_page.get_welcome_message()def test_failed_login(login_page):login_page.enter_username("admin").enter_password("wrong")login_page.click_login()assert "Invalid password" in login_page.get_error_message()
三、POM 的优势
优势 | 说明 |
---|---|
可维护性 | 元素选择器变更只需修改 Page 类,无需修改测试脚本。 |
复用性 | 多个测试场景可复用同一 Page 类的方法(如 |
可读性 | 测试脚本读起来像用户手册(如 |
协作友好 | 开发与测试可并行:开发提供 Page 类,测试编写 Gherkin 场景。 |
总结
POM 的核心是 “将页面抽象为对象,操作抽象为方法”。通过分层设计:
-
Page 类:封装元素和操作
-
测试脚本:只关心业务逻辑(如“登录成功”)
-
Gherkin:描述行为而非实现
这种模式让自动化测试代码更健壮、更易应对需求变更。