Page Object 软件测试项目结构+代码

📅 2026/7/2 21:08:02 👁️ 阅读次数 📝 编程学习
Page Object 软件测试项目结构+代码

本项目基于Selenium相关习题-CSDN博客修改

一、项目目录结构(简历级)

创建以下文件:

selenium_web_automation_framework/ ├── pages/ # 页面对象层 │ ├── __init__.py │ ├── base_page.py # 基类:封装通用操作 │ ├── bilibili_page.py # B站首页对象 │ └── login_page.py # 登录练习站对象 ├── testcases/ # 测试用例层 │ ├── __init__.py │ ├── test_bilibili_search.py # B站搜索用例 │ └── test_login.py # 登录用例(数据驱动) ├── data/ # 测试数据 │ └── login_data.xlsx # 登录测试数据Excel ├── conftest.py # driver fixture ├── requirements.txt # 依赖库 ├── run_tests.py # 一键运行入口 └── README.md # 项目说明(面试加分项)

如图所示:

二、具体代码和数据

1)testdata_pytest.xlsx—— Excel 数据样例

2)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 self.wait = WebDriverWait(driver, 10) def find_element(self, locator): """等待元素存在并返回""" return self.wait.until(EC.presence_of_element_located(locator)) def click_element(self, locator): """等待元素可点击后点击""" self.wait.until(EC.element_to_be_clickable(locator)).click() def input_text(self, locator, text): """等待元素可交互后输入""" element = self.wait.until(EC.element_to_be_clickable(locator)) element.clear() element.send_keys(text) def get_text(self, locator): """获取元素文本""" return self.find_element(locator).text def switch_to_new_window(self): """切换到最新打开的标签页""" handles = self.driver.window_handles self.driver.switch_to.window(handles[-1])

3)bilibili_page.py—— B站首页搜索

from selenium.webdriver.common.by import By from pages.base_page import BasePage class BilibiliPage(BasePage): URL = "https://www.bilibili.com/" # 定位器(集中管理,页面变化只改这里) SEARCH_INPUT = (By.XPATH, '//*[@id="nav-searchform"]/div[1]/input') SEARCH_BUTTON = (By.XPATH, '//*[@id="nav-searchform"]/div[2]') def open(self): self.driver.get(self.URL) def search(self, keyword): self.input_text(self.SEARCH_INPUT, keyword) self.click_element(self.SEARCH_BUTTON) # 搜索后B站会打开新标签页,自动切换过去 self.switch_to_new_window() def get_page_title(self): return self.driver.title

4)login_page.py—— 练习登录站

from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException from pages.base_page import BasePage class LoginPage(BasePage): URL = "https://practicetestautomation.com/practice-test-login/" # 定位器 USERNAME_INPUT = (By.ID, "username") PASSWORD_INPUT = (By.ID, "password") SUBMIT_BUTTON = (By.ID, "submit") LOGOUT_BUTTON = (By.XPATH, '//*[@id="loop-container"]/div/article/div[2]/div/div/div/a') ERROR_MESSAGE = (By.ID, "error") # 如果有错误提示 def open(self): self.driver.get(self.URL) def enter_username(self, username): self.input_text(self.USERNAME_INPUT, username) def enter_password(self, password): self.input_text(self.PASSWORD_INPUT, password) def click_login(self): self.click_element(self.SUBMIT_BUTTON) def login(self, username, password): """完整登录操作""" self.enter_username(username) self.enter_password(password) self.click_login() def is_logout_displayed(self): """判断登录是否成功:返回True/False""" try: self.get_text(self.LOGOUT_BUTTON) return True except TimeoutException: return False def get_logout_text(self): return self.get_text(self.LOGOUT_BUTTON)

5)test_bilibili_search.py—— B站搜索用例

import pytest from pages.bilibili_page import BilibiliPage from conftest import driver class TestBilibiliSearch: def test_search_earth(self, driver): """测试搜索'地球',结果页标题应包含关键词""" # assert True bilibili_page = BilibiliPage(driver) bilibili_page.open() bilibili_page.search("地球") assert "地球" in bilibili_page.get_page_title() # print('aaa')

6)test_login.py—— 登录数据驱动

import pytest import openpyxl from pages.login_page import LoginPage from conftest import driver def get_login_data(): """从Excel读取测试数据,返回 (username, password, expected_result)""" workbook = openpyxl.load_workbook('C:/study/python/selenium_web_automation_framework/data/testdata_pytest.xlsx') sheet = workbook.active data = [] for row in sheet.iter_rows(min_row=2, values_only=True): data.append(row) return data class TestLogin: @pytest.mark.parametrize("username,password,expected", get_login_data()) def test_login(self, driver, username, password, expected): login_page = LoginPage(driver) login_page.open() login_page.login(username, password) if expected == "登录成功": assert login_page.is_logout_displayed(), "应该显示Log out按钮" else: assert not login_page.is_logout_displayed(), "不应该登录成功"

7)conftest.py —— 全局 driver fixture

from selenium import webdriver from selenium.webdriver.chrome.service import Service import pytest @pytest.fixture def driver(): # 根据你的ChromeDriver路径修改 d = webdriver.Chrome(service=Service('C:/study/python/selenium_web_automation_framework/chromedriver.exe')) d.maximize_window() yield d # 这个d会传给测试函数 d.quit() # 测试结束后自动执行

8)run_tests.py —— 一键运行并生成报告(为 Allure 预留)

import pytest import os if __name__ == "__main__": # 运行所有用例,生成Allure报告数据 pytest.main([ "-v", "--alluredir=./reports/allure-results", "./testcases/" ]) # 自动打开报告(确保已安装allure) os.system("allure serve ./reports/allure-results")

9)requirements.txt(安装命令:pip install -r requirements.txt)

selenium>=4.0 pytest>=7.0 openpyxl>=3.0

三、运行结果

1)提前安装allure并配置环境变量,如图所示:

2)在pycharm命令行,cd到python_run_tests.py所在目录下运行python run_tests.py,如图所示:

3)运行结果如图所示: