当前位置: 首页 > news >正文

PageObject模式实战案例

自动化测试神器PageObject:代码减少50%,维护成本降70%

01 自动化测试的噩梦:改一个元素,全局崩溃

“登录页面改了个按钮ID,跑了3年的脚本全挂了。”

这是某测试团队的真实故事。一个小改动,200+测试用例全部失败,修了整整2天。

问题的根源在于:测试代码和页面元素绑定了。

而PageObject模式,就是来解决这个问题的。

02 什么是PageObject?一句话解释

PageObject = 把页面当对象封装。

每个页面对应一个类,页面上的元素是这个类的属性,操作是这个类的方法。

# ❌ 传统写法:元素和操作混在一起deftest_login():driver.find_element(By.ID,"username").send_keys("admin")driver.find_element(By.ID,"password").send_keys("123456")driver.find_element(By.ID,"login-btn").click()assert"首页"indriver.title
# ✅ PageObject写法:元素封装进页面类classLoginPage:def__init__(self,driver):self.driver=driverdefinput_username(self,username):self.driver.find_element(By.ID,"username").send_keys(username)definput_password(self,password):self.driver.find_element(By.ID,"password").send_keys(password)defclick_login(self):self.driver.find_element(By.ID,"login-btn").click()deflogin(self,username,password):self.input_username(username)self.input_password(password)self.click_login()# 测试用例简洁到极致deftest_login():LoginPage(driver).login("admin","123456")assert"首页"indriver.title

03 3层架构,让测试代码像乐高一样拼

第1层:页面对象层(PageObjects)

每个页面一个类,只管元素定位和方法封装。

classLoginPage:def__init__(self,driver):self.driver=driver@propertydefusername_input(self):returnself.driver.find_element(By.ID,"username")@propertydeflogin_button(self):returnself.driver.find_element(By.ID,"login-btn")deflogin(self,username,password):self.username_input.send_keys(username)self.driver.find_element(By.ID,"password").send_keys(password)self.login_button.click()

第2层:业务逻辑层(TestSteps)

封装业务流程,一个方法完成一系列操作。

classLoginSteps:def__init__(self,driver):self.login_page=LoginPage(driver)deflogin_with_valid_user(self):self.login_page.login("admin","password123")# 等待跳转time.sleep(2)returnHomePage(self.driver)deflogin_with_invalid_user(self):self.login_page.login("admin","wrongpassword")returnself.login_page.get_error_message()

第3层:测试用例层(TestCases)

只写"做什么",不写"怎么做"。

deftest_login_success():steps=LoginSteps(driver)home_page=steps.login_with_valid_user()asserthome_page.get_title()=="首页"deftest_login_failure():steps=LoginSteps(driver)error_msg=steps.login_with_invalid_user()assert"用户名或密码错误"inerror_msg

04 真实项目实战:电商后台登录

项目结构:

tests/ ├── pages/ │ ├── __init__.py │ ├── login_page.py │ ├── home_page.py │ └── admin_page.py ├── steps/ │ ├── __init__.py │ └── login_steps.py ├── cases/ │ ├── __init__.py │ └── test_login.py └── conftest.py

login_page.py(完整代码):

fromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECclassLoginPage:# 元素定位器USERNAME_INPUT=(By.ID,"username")PASSWORD_INPUT=(By.ID,"password")LOGIN_BUTTON=(By.ID,"login-btn")ERROR_MSG=(By.CLASS_NAME,"error-message")REMEMBER_CHECKBOX=(By.ID,"remember-me")def__init__(self,driver):self.driver=driver self.wait=WebDriverWait(driver,10)definput_username(self,username):self.wait.until(EC.presence_of_element_located(self.USERNAME_INPUT))self.driver.find_element(*self.USERNAME_INPUT).clear()self.driver.find_element(*self.USERNAME_INPUT).send_keys(username)definput_password(self,password):self.driver.find_element(*self.PASSWORD_INPUT).clear()self.driver.find_element(*self.PASSWORD_INPUT).send_keys(password)defcheck_remember_me(self):checkbox=self.driver.find_element(*self.REMEMBER_CHECKBOX)ifnotcheckbox.is_selected():checkbox.click()defclick_login(self):self.driver.find_element(*self.LOGIN_BUTTON).click()deflogin(self,username,password,remember=False):self.input_username(username)self.input_password(password)ifremember:self.check_remember_me()self.click_login()defget_error_message(self):returnself.wait.until(EC.presence_of_element_located(self.ERROR_MSG)).text

05 为什么要用PageObject?数据说话

指标传统写法PageObject
元素变更影响范围200+用例1个文件
代码重复率60%+<10%
维护时间/周8小时2小时
新人上手成本3天1天

一句话总结:PageObject不是必须,但它是让自动化测试活下来的唯一出路。


知识星球:软件测试成长圈

http://www.jsqmd.com/news/711752/

相关文章:

  • 突破性自托管游戏串流:Sunshine实战配置与性能优化深度解析
  • 全网最全网安合规资源站汇总,从入门到挖洞收藏这篇就够
  • 终极惠普OMEN游戏本性能优化指南:OmenSuperHub开源工具完全解析
  • AI智能体协作失控?15条规则打造可靠AI编程助手
  • CnOpenData 税收调查企业发明专利授权质量统计表
  • 反向海淘爆发期,taocarts如何用技术破解代购供应链对接难题
  • Parler TTS低资源语言适配实战:从数据准备到模型部署
  • Pyodide包管理完全指南:在浏览器中运行Python生态系统的终极方案
  • Cosbench分布式压测集群搭建踩坑实录:多Driver配置与防火墙那些事儿
  • 猫抓插件终极指南:如何免费下载网页视频音频资源
  • 乐山临江鳝丝优质门店推荐榜 非遗传承领衔 - 优质品牌商家
  • WASM插件在Docker边缘集群中无法加载?5个致命错误诊断清单,含内核级调试命令速查表
  • DCDC的电感布局
  • AI生成代码检测:方法与实战解析
  • 2026 最新网页游戏排行榜 人气口碑双高作品盘点
  • Agent 项目落地模板
  • 大模型学习:从提示工程到上下文工程,小白程序员必备(收藏版)
  • 大模型开发宝典:小白/程序员轻松上手,收藏必备,速成大模型开发高手
  • 心理声学音频质量测量技术解析与应用
  • 2026年,宸合健康为高净值家庭提供专属肝胆排毒与代谢调理高端健康管理方案
  • 85欧姆差分阻抗系统测试与S参数转换技术
  • 代购运营效率翻倍!taocarts自动化功能实战
  • ARM架构缓存与计数器寄存器深度解析
  • C++基础(十四)——异常处理与错误管理
  • 3CTEST全新推出100Hz~10MHz卡式宽带电流监测钳 CCM 0210M
  • ETASOLUTIONS钰泰 ETA2821S2G SOT23-6 DC-DC电源芯片
  • UV 固化三防漆 PCB 防护工艺规范 V1.0(基于 K-5065 实测数据)
  • 中小微企业进销存怎么选?管家通三款产品闭眼入清单(500-2000元)
  • 构建对人类有益的AI:价值对齐与安全设计实践
  • 深入浅出解析Transformer核心机制QKV,助你轻松掌握大模型技术(收藏版)