转载请注明出处️

作者:IT小学生蔡坨坨

原文链接:五分钟搞懂POM设计模式


大家好,我是IT小学生蔡坨坨。

今天,我们来聊聊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的引入

历史

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框架

GitHub:关注VX公众号 IT小学生蔡坨坨 获取

  • 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 生成的定制化报告

五分钟搞懂POM设计模式的更多相关文章

  1. 五分钟搞懂Vuex

    这段时间一直在用vue写项目,vuex在项目中也会依葫芦画瓢使用,但是总有一种朦朦胧胧的感觉.于是决定彻底搞懂它. 看了一下午的官方文档,以及资料,才发现vuex so easy! 作为一个圈子中的人 ...

  2. 五分钟搞懂什么是B-树(全程图解)【转】

    前戏 我们大家都知道动态查找树能够提高查找效率,比如:二叉查找树,平衡二叉查找树,红黑树.他们查找效率的时间复杂度O(log2n),跟树的深度有关系,那么怎么样才能提高效率呢?当然最快捷的方式就是减少 ...

  3. 五分钟搞懂 Linux 重点知识,傻瓜都能学会!

    来源:无痴迷,不成功 www.cnblogs.com/justmine/p/9053419.html 写在前面 我们都知道Linux是一个支持多用户.多任务的系统,这也是它最优秀的特性,即可能同时有很 ...

  4. 五分钟搞懂MySQL索引下推

    大家好,我是老三,今天分享一个小知识点--索引下推. 如果你在面试中,听到MySQL5.6"."索引优化" 之类的词语,你就要立马get到,这个问的是"索引下推 ...

  5. 五分钟搞懂spring-cloud-square

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 初识spring-cloud-square 2021年 ...

  6. 五分钟搞定Go.js

    五分钟搞定Go.js  1.基于html5~因为Go.js是一个依赖于HTML5特性的JavaScript库,所以需要确保您的页面声明它是一个HTML5文档,当然需要加载库 <!DOCTYPE ...

  7. zookeeper-架构设计与角色分工-《每日五分钟搞定大数据》

    本篇文章阅读时间5分钟左右 点击看<每日五分钟搞定大数据>完整思维导图   zookeeper作为一个分布式协调系统,很多组件都会依赖它,那么此时它的可用性就非常重要了,那么保证可用性的同 ...

  8. zookeeper核心-zab协议-《每日五分钟搞定大数据》

    上篇文章<paxos与一致性>说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Bro ...

  9. HDFS-异常大全-《每日五分钟搞定大数据》

    点击看<每日五分钟搞定大数据>完整思维导图以及所有文章目录 问题1:Decomminssioning退役datanode(即删除节点) 1.配置exclude: <name>d ...

随机推荐

  1. 142. 环形链表 II

    做题思路 or 感想 : 1,这一题用快慢指针来判断是否有环,快慢指针同一起点,速度不同,如果有环,则必定会相遇 2,第二个有意思的点就是数论环节来弄出环入口了,真的太精妙了,但因为我表述能力不好,这 ...

  2. WIN进程注入&BypassUAC&令牌窃取

    WIN进程注入&BypassUAC&令牌窃取 本地提权-win令牌窃取 假冒令牌可以假冒一个网络中的另一个用户进行各类操作. 所以当一个攻击者需要域管理员的操作权限时候,需通过假冒域管 ...

  3. linux压缩打包、定时任务

    压缩打包 gzip压缩 win中的压缩包:zip rar Linux常见的压缩包有哪些? gzip bzip2 1.gzip压缩 压缩命令:gzip [压缩文件] 解压命令:gzip -d [压缩包] ...

  4. linux压缩及解压命令

    .zip文件:压缩:zip,解压:unzip 如果要解压到指定目录,可以加上 -d 选项 .gz文件:压缩:gzip,解压:gunzip 压缩.解压缩后原文件丢失,可以加上 -c 选项利用 linux ...

  5. 面试官:RabbitMQ过期时间设置、死信队列、延时队列怎么设计?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 RabbitMQ我们经常的使用, ...

  6. 项目开发字符串模型strstr_while

    #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <std ...

  7. Go学习-基本语法(一)

    前言 一直对Service Mesh相关内容比较感兴趣,后面一路学习了Dcoker.Kubernetes等相关内容,可以说是对基本概念和使用有一定了解,随着开始学习一些相关的组件的时候,发现基本上全部 ...

  8. 漏洞复现:使用Kali制作木马程序

    漏洞复现:使用Kali制作木马程序 攻击机:Kali2019 靶机:Win7 64位 攻击步骤: 1.打开Kali2019和Win7 64位虚拟机,确定IP地址在一个网段 2.确定好IP地址,进入Ka ...

  9. Redis实现并发阻塞锁方案

    由于用户同时访问线上的下订单接口,导致在扣减库存时出现了异常,这是一个很典型的并发问题,本篇文章为解决并发问题而生,采用的技术为Redis锁机制+多线程的阻塞唤醒方法. 在实现Redis锁机制之前,我 ...

  10. tensorflwo-gpu win10_64bit 的安装版本问题

    tensorflow 1.3 配 cuda8.0 + cudnn5.1tensorflow 1.4 配 cuda8.0 + cudnn6.0 有没有更大的字体???我要配!!!!!