自动化测试-Page分层
在自动化测试中,Page 分层(Page Layering)是一种设计模式,通常与 页面对象模式(Page Object Model, POM) 结合使用,以进一步提高测试代码的可维护性、可读性和复用性。Page 分层将页面对象进一步拆分为多个层次,每个层次负责不同的职责,从而降低代码的耦合度。
1. 为什么需要 Page 分层?
- 降低耦合度:将页面逻辑、元素定位和操作分离,使代码更易于维护。
- 提高复用性:通用操作可以抽象到基类中,供多个页面复用。
- 增强可读性:分层后,测试用例更简洁,逻辑更清晰。
- 便于扩展:新增页面或功能时,只需在相应层次中添加代码,无需修改其他部分。
2. Page 分层的常见结构
通常,Page 分层可以分为以下几层:
(1)元素层(Element Layer)
- 职责:定义页面中的元素定位方式。
- 示例:将元素的定位器(如
By.ID
、By.XPATH
)封装到单独的类或字典中。
(2)操作层(Action Layer)
- 职责:封装对页面元素的操作(如点击、输入、获取文本)。
- 示例:将常用的操作(如登录、搜索)封装成方法。
(3)页面层(Page Layer)
- 职责:组合元素层和操作层,提供完整的页面功能。
- 示例:将登录页面的元素和操作封装到
LoginPage
类中。
(4)业务层(Business Layer)
- 职责:组合多个页面的操作,实现完整的业务流程。
- 示例:将登录、搜索、下单等操作组合成一个完整的测试用例。
3. Page 分层的实现示例
以下是一个基于 Selenium 和 Pytest 的 Page 分层实现示例。
目录结构
automation_framework/ ├── pages/ │ ├── elements/ # 元素层 │ │ ├── login_elements.py │ │ └── home_elements.py │ ├── actions/ # 操作层 │ │ ├── login_actions.py │ │ └── home_actions.py │ ├── login_page.py # 页面层 │ └── home_page.py ├── tests/ # 业务层 │ └── test_login.py └── conftest.py # Pytest 配置
(1)元素层
pages/elements/login_elements.py
from selenium.webdriver.common.by import By class LoginElements: USERNAME_FIELD = (By.ID, "username") PASSWORD_FIELD = (By.ID, "password") LOGIN_BUTTON = (By.ID, "login-btn")
(2)操作层
pages/actions/login_actions.py
from selenium.webdriver.common.keys import Keys class LoginActions: def __init__(self, driver): self.driver = driver def enter_username(self, username): self.driver.find_element(*LoginElements.USERNAME_FIELD).send_keys(username) def enter_password(self, password): self.driver.find_element(*LoginElements.PASSWORD_FIELD).send_keys(password) def click_login(self): self.driver.find_element(*LoginElements.LOGIN_BUTTON).click()
(3)页面层
pages/login_page.py
from .elements.login_elements import LoginElements from .actions.login_actions import LoginActions class LoginPage: def __init__(self, driver): self.driver = driver self.actions = LoginActions(driver) def login(self, username, password): self.actions.enter_username(username) self.actions.enter_password(password) self.actions.click_login()
(4)业务层
tests/test_login.py
import pytest from pages.login_page import LoginPage from utils.browser import Browser from utils.data_loader import load_config @pytest.fixture(scope="module") def browser(): config = load_config("config/config.yaml") browser = Browser(config) browser.start() yield browser browser.quit() def test_login_success(browser): login_page = LoginPage(browser.driver) browser.driver.get("https://example.com/login") login_page.login("testuser", "password123") assert "Welcome" in browser.driver.page_source
4. Page 分层的优势
- 清晰的责任划分:每个层次只负责特定的职责,代码更易于理解和维护。
- 高复用性:通用操作可以抽象到基类中,供多个页面复用。
- 易于扩展:新增页面或功能时,只需在相应层次中添加代码,无需修改其他部分。
- 提高可读性:测试用例更简洁,逻辑更清晰。
5. 最佳实践
- 避免过度分层:分层过多会增加代码复杂度,建议根据项目规模合理分层。
- 使用基类:将通用操作(如元素等待、截图)抽象到基类中。
- 命名规范:使用清晰的命名规则,便于理解每个层次的职责。
- 数据驱动:结合数据驱动测试,提高测试用例的灵活性。
6. 示例:基类设计
pages/base_page.py
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class BasePage: def __init__(self, driver): self.driver = driver def wait_for_element(self, locator, timeout=10): return WebDriverWait(self.driver, timeout).until( EC.visibility_of_element_located(locator) ) def take_screenshot(self, filename): self.driver.save_screenshot(filename)
pages/login_page.py(继承基类)
from .base_page import BasePage from .elements.login_elements import LoginElements from .actions.login_actions import LoginActions class LoginPage(BasePage): def __init__(self, driver): super().__init__(driver) self.actions = LoginActions(driver) def login(self, username, password): self.actions.enter_username(username) self.actions.enter_password(password) self.actions.click_login()
通过 Page 分层设计,可以构建一个结构清晰、易于维护的自动化测试框架,适用于企业级项目的长期发展。
进阶高级测试工程师 文章被收录于专栏
《高级软件测试工程师》专栏旨在为测试领域的从业者提供深入的知识和实践指导,帮助大家从基础的测试技能迈向高级测试专家的行列。 在本专栏中,主要涵盖的内容: 1. 如何设计和实施高效的测试策略; 2. 掌握自动化测试、性能测试和安全测试的核心技术; 3. 深入理解测试驱动开发(TDD)和行为驱动开发(BDD)的实践方法; 4. 测试团队的管理和协作能力。 ——For.Heart