五分钟搞懂POM设计模式

news2024/9/28 17:22:41

今天,我们来聊聊Web UI自动化测试中的POM设计模式。

为什么要用POM设计模式
前期,我们学会了使用Python+Selenium编写Web UI自动化测试线性脚本

线性脚本(以快递100网站登录举栗):

import time

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://sso.kuaidi100.com/sso/v2/authorize.do")
driver.maximize_window()
driver.find_element(By.ID, 'name').send_keys("***********")
driver.find_element(By.ID, 'password').send_keys("***********")
driver.find_element(By.ID, 'submit').click()
time.sleep(2)
text = driver.find_element(By.PARTIAL_LINK_TEXT, '首页').text
assert text == '首页'
driver.close()

使用以上代码,最基础最简单的Web UI 自动化测试就做起来了,但是,问题也随之而来,线性脚本的缺点也暴露出来了:

  • Web UI自动化测试,简单来说,就是模拟人在浏览器上的操作,打开浏览器-定位元素-操作元素-模拟页面动作-断言结果
  • 由于线性脚本中的元素定位、元素操作细节、测试数据、结果验证(断言)是捆绑在一起的,代码会显得非常冗余、可读性差、不可复用、工作量大且可维护性差
    刚开始,少数的测试用例维护起来可能很容易,但随着时间迁移、产品迭代、测试套件持续增长,脚本也越来越臃肿,可能需要维护几十个页面,且很多页面是公用的,元素的任何改变都会让我们的脚本变的繁琐复杂、耗时易出错。例如:十几个用例中都用到了A元素,某一天A元素被前端改成了B元素,我们就需要去十几个用到A元素的地方,将A元素修改为B元素
  • 如果可以把公共元素抽取出来,即使元素被前端修改,我们也只需更新元素的定位方式,而不用修改每条测试用例,无论多少用例用到该元素,都只需修改元素定位方式,重新获取元素即可
  • 所以我们引入了PageObject这种解决方案,它可以帮我们解决设计上的问题,可以将testcase和page分层,形成一个非常好的结果

什么是POM设计模式

  • POM:Page Object Model,页面对象模型的简称

  • 2013年,由Martin Fowler提出了PageObject的观点

在这里插入图片描述

  • 作者的观点是一种封装思想,旨在为每个待测页面创建一个页面对象,从而将繁琐的定位操作、操作细节封装到这个页面对象中,对外只提供必要的操作接口,在调用的时候只调用提供的接口,不用去调用操作细节,最终实现程序的高内聚低耦合,使程序模块的可重用性、移植性大大增强

  • 在这种模式下,对于应用程序中的每个页面都应该有相应单独的页面类(例如:login_page、userinfo_page),类中应该包含此页面上的元素对象和操作这些元素对象所需要的方法

  • 再将流程所关联的页面作为对象,将对象串联起来形成不同的业务流程,例如:在登录页面完成登录操作后跳转到用户中心页面进行个人信息的修改

Selenium官方对PageObject的引入

历史

  • 2015年,Selenium官方对PageObject进行引入:
  • https://github.com/SeleniumHQ/selenium/wiki/PageObjects

在这里插入图片描述
2020年,Selenium更新文档地址:

https://www.selenium.dev/documentation/test_practices/encouraged/page_object_models

在这里插入图片描述
PageObject六大原则


The public methods represent the services that the page offers

用公共方法表示页面提供的服务

例如:登录页面,有用户名输入框、密码输入框、登录按钮,于是就可以用input_username()代表输入用户名、用input_password()代表输入密码、用click_submit()代表点击登录按钮

Try not to expose the internals of the page

尽量不要暴露页面的内部信息

将操作细节封装成方法,对外只提供对应的方法供调用

Generally don’t make assertions

一般不使用断言

断言要和Page代码分开,不要将断言写在PageObject层

Methods return other PageObjects

方法返回其他PageObjects

例如:首页有个方法是点击登录图标跳转到登录页面,因此这个方法应该返回login_page

Need not represent an entire page

不需要表示整个页面

不需要对页面中的每一个元素进行建模,只需要关注我们需要用到的元素。例如:登录页面除了账号密码登录,还有快捷登录、手机短信登录、扫码登录等

Different results for the same action are modelled as different methods

同一行为的不同结果可以用不同的方法来模拟

例如:对一个页面进行操作,可能出现正确的结果或者错误的结果,可以为这两种不同的结果分别创建两个不同的方法

POM框架


base:base_page,基类,定义项目所需的基础方法,对Selenium一些常用的api进行二次封装,如:find_element、click、send_keys、screenshot、调用JavaScript脚本的方法以及其他与浏览器相关的操作

为什么要有基类?

由于每个页面都会频繁使用这些方法,若单纯使用Selenium原始api,可能遇到一些问题,例如:某个按钮未加载完成,但已触发了点击事件,导致元素定位不到而报错。这时就可以对原始api进行二次封装,如:加入等待时间、对异常进行捕获并打印日志等,之后所有的PageObject都继承BasePage类,后续只需要调用这些封装好的方法,增强复用性
假设以后不使用Selenium这个框架,就只需要修改BasePage中的方法,不用去修改具体的测试用例业务代码
pages:page_object,页面对象层,也是PO的核心层,继承BasePage,管理页面元素以及操作元素的方法(将操作元素的动作写成方法)

cases:测试用例层,用于管理测试用例,这里会用到单元测试框架,如:Pytest、Unittest。

data:测试数据层,用于测试数据的管理,数据与脚本分离,降低维护成本,提高可移植性,如:yml 文件数据

config:配置文件层,存放整个项目需要用到的配置项,如:URL、数据库信息等

utils:CommonUtil,公共模块,将一些公共函数、方法以及通用操作进行封装,如:日志模块、yaml 操作模块、时间模块等

run.py:批量执行测试用例的主程序,根据不同需求不同场景进行组装,遵循框架的灵活性和扩展性

logs:日志模块,用于记录和管理日志,针对不同情况,设置不同的日志级别,方便定位问题

reports:测试报告层,用于测试报告的生成和管理,如:基于 Allure 生成的定制化报告


最后:下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取 【保证100%免费】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/366555.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R统计绘图 | 物种组成堆叠柱形图(绝对/相对丰度)

一、数据准备 数据使用的不同处理土壤样品的微生物组成数据,包含物种丰度,分类单元和样本分组数据。此数据为虚构,可用于练习,请不要作他用。 # 1.1 设置工作路径 #knitr::opts_knit$set(root.dir"D:\\EnvStat\\PCA")#…

[python入门(51)] - python时间日期格式time和datetime

目录 ❤ 预备知识 ❤ UTC time Coordinated Universal Time ❤ epoch time ❤ timestamp(时间戳) ❤ stamptime时间戳 ❤ struct_time时间元组 ❤ format time 格式化时间 ❤ time模块​编辑 ❤ 获取当前时间的方法 ❤ 当传入默认参…

阿里云ECS TOP性能提升超20%!KeenTune助力倚天+Alinux3达成开机即用的全栈性能调优 | 龙蜥技术

文/KeenTune SIG01阿里云 ECS 上售卖页新增“应用加速”功能2023年1月12日 阿里云 ECS 的售卖页有了一些新的变化,在用户选择倚天 Alinux3 新建实例时,多了一个新的选项“应用加速”。这个功能是 阿里云 ECS 基于 KeenTune 提供典型云场景的开机即用的全…

翻转链表k个元素——递归

题目描述25. K 个一组翻转链表难度困难1920收藏分享切换为英文接收动态反馈给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那…

【Python入门第十六天】Python If ... Else

Python 条件和 If 语句 Python 支持来自数学的常用逻辑条件&#xff1a; 等于&#xff1a;a b不等于&#xff1a;a ! b小于&#xff1a;a < b小于等于&#xff1a;a < b大于&#xff1a;a > b大于等于&#xff1a;a > b 这些条件能够以多种方式使用&#xff0c…

再析jvm

前言 希望自己每一次学习都有不同的理解 文章目录前言1. jvm的组成取消永久代使用元空间原因2. 运行时数据区3. 堆栈区别队列和栈&#xff0c;队列先进先出&#xff0c;栈先进后出从栈顶弹出4. GC、内存溢出、垃圾回收4.1 如何确定引用是否会被回收4.1.1 Java中的引用类型4.1.…

OpenStack手动分布式部署Glance【Queens版】

目录 Glance简介 1、登录数据库配置&#xff08;在controller执行&#xff09; 1.1登录数据库 1.2数据库里创建glance 1.3授权对glance数据库的正确访问 1.4退出数据库 1.5创建glance用户密码为000000 1.6增加admin角色 1.7创建glance服务 1.8创建镜像服务API端点 2、安装gla…

LeetCodeHOT100热题02

写在前面 主要是题目太多&#xff0c;所以和前面的分开来记录。有很多思路的图都来源于力扣的题解&#xff0c;如侵权会及时删除。不过代码都是个人实现的&#xff0c;所以有一些值得记录的理解。之前的算法系列参看&#xff1a; 剑指offer算法题01剑指offer算法题02 七、动…

SQL零基础入门学习(八)

SQL零基础入门学习&#xff08;七&#xff09; SQL 连接(JOIN) SQL join 用于把来自两个或多个表的行结合起来。 下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。 SQL JOIN SQL JOIN 子句用于把来自两个或多个表的行结合起来&#xff0c;基…

TensorBoard自定义修改单条及多条曲线颜色

在深度学习可视化训练过程中&#xff0c;曲线颜色是随机的&#xff0c;想要将好看的曲线颜色图放到论文中&#xff0c;就得自定义曲线颜色&#xff0c;具体方法见下文。 目录一、下载svg文件二、修改svg文件三、修改后曲线颜色对比四、总结一、下载svg文件 在TensorBoard界面中…

webman 连接 oracle

composer require topthink/think-oraclev2.1 配置文件 thinkorm.php return [ default > oracle, connections > [ oracle > [ // 数据库类型 type > oracle, // 服务器地址 hostname > 192…

多语言解决方案

文章目录背景整体方案多语言管理端客户端流水线其他背景 多语言是一个比较麻烦的事情&#xff0c;特别是当 App 比较大的时候&#xff0c;还会涉及到多个部门的开发以及翻译人员&#xff0c;这中间可能会存在比较大的沟通成本&#xff0c;而且还可能会阻塞开发的进度。以下是我…

【JavaEE初阶】第二节.多线程( 进阶篇 ) 锁的优化、JUC的常用类、线程安全的集合类

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、synchronized的优化操作 1.1 锁膨胀/锁升级 1.2 锁消除 1.3 锁粗化二、JUC 2.1 Callable接口 2.2 ReentrantLock类&…

Python获取中国大学MOOC某课程评论及其参与人数

文章目录前言一、需求二、分析三、运行结果前言 本系列文章来源于真实的需求本系列文章你来提我来做本系列文章仅供学习参考 一、需求 1、课程参加人数 2、课程学员名称及其评论 二、分析 首先查看网页源代码是否有需要的数据 课程参加人数 课程学员名称及其评论 F12 打开浏…

Linux中断处理

目录 一、什么是中断 二、中断处理原理 三、中断接口 3.1 中断申请 3.2 中断释放 3.3 中断处理函数原型 四、按键驱动 一、什么是中断 一种硬件上的通知机制&#xff0c;用来通知CPU发生了某种需要立即处理的事件 分为&#xff1a; 1. 内部中断 CPU执行程序的过程中&am…

力扣sql简单篇练习(二十)

力扣sql简单篇练习(二十) 1 广告效果 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT ad_id,IFNULL(ROUND(sum(IF(actionClicked,action,0))/sum(IF(actionIgnored,0,1))*100,2),0.00) ctr FROM Ads GROUP BY ad_id ORDER BY ctr desc,ad_id …

消息队列MQ介绍

消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。通过消息队列&#xff0c;应用程序可独立地执行--它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。 消息中间件概述 消息队列技术是…

Wi-Fi 7技术揭秘

引言 2022年4月7日&#xff0c;紫光股份旗下新华三集团全球首发企业级智原生Wi-Fi 7 AP新品 WA7638和WA7338。仅在同年的6月15日&#xff0c;在东京举行的第29届日本网络通信展览会&#xff08;Interop Tokyo 2022&#xff0c;简称Interop展&#xff09;中&#xff0c;WA7638就…

Java - 数据结构,栈

一、栈 1.1、什么是栈 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压…

关于《How to Learn to Code Get a Developer Job in 2023》的经验学习

1. Who is This Book For ? for Anyone who is considering a career in software development. 2. Can Anyone Learn to Code? Any sufficiently motivated person can learn to code. 3.Executive Summary Learning to code is hard.Getting a job as a software devel…