PO模式在selenium自动化测试框架的优势


Posted in Python onMarch 20, 2022

PO模式简介

1.什么是PO模式

PO模型是:Page Object Model的简写 页面对象模型

作用:就是把测试页面和测试脚本进行分离,即把页面封装成类,供测试脚本进行调用;

分层机制,让不同层去做不同类型的事情,让代码结构清晰,增加复用性。

PO设计模式是Selenium自动化测试中最佳的设计模式之一,主要体现在对界面交互细节的封装

2. 不使用PO设计会出现以下几种情况:

复用性不太好,扩展性不好,易读性差,不好维护,UI界面频繁的项目维护起来比较麻烦。

3.PO模式的优缺点

优点:

  • 提高代码的可读性
  • 减少了代码的重复
  • 提高代码的可维护性,特别是针对UI界面频繁的项目

缺点:

  • 造成项目结构比较复杂,因为是根据流程进行了模块化处理

下面重点看下PO模式在selenium自动化测试框架的优势。

PO模式是在UI自动化测试过程当中使用非常频繁的一种设计模式,使用这种模式后,可以有效的提升代码的复用能力,并且让自动化测试代码维护起来更加方便。

PO模式的全称叫page object model(POM),有时候叫做 page object pattern。最开始由马丁福勒提出,这个模式受到selenium自动化测试框架大力推广,因而成为一种非常主流的自动化测试设计模式。

在PO模式当中,每一个UI页面使用编程语言当中的类来表示。在这个类当中,通过函数形式定义页面的行为和操作。这让调用方不需要关注具体执行的操作到底是点击还是拖动,而是关注具体的业务,比如登录、购物等等,甚至如果程序员直接把代码给产品经理看,他也是能看懂的。

PO模式在selenium自动化测试框架的优势

没有使用PO模式时

在测试用例中直接编写浏览器操作API,对于代码编写者并没有多高的难度,因为他自己已经对这些API非常熟悉,但是这些浏览器操作并不能体现业务,至少没有产品经理那么熟悉,因此他很难和产品经理进行沟通,也难和开发沟通,甚至在半个月之后,他已经忘记了自己到底写了什么东西。

def test_login_mail(self):
    driver = self.driver
    driver.get("http://www.xxx.xxx.com")
    driver.find_element_by_id("idInput").clear()
    driver.find_element_by_id("xxxxxxx").send_keys("xxxxx")
    driver.find_element_by_id("xxxxxxx").clear()
    driver.find_element_by_id("xxxxxxx").send_keys("xxxxxx")
    driver.find_element_by_id("loginBtn").click()

使用PO模式

使用PO模式有利于梳理业务,也有利于和其他人进行沟通。当你把下面这段代码拿给产品经理看的时候,他也大概能知道你测的是什么业务,能帮你纠正你的测试流程是否正确,或者提出一些更有建设性的意见,这对于大型项目需要频繁沟通和梳理业务时非常有用。

def test_login_mail(self):
    LoginPage(driver).login()

而浏览器本身的操作,就会被分离到一个更底层的模块,这些代码你可以不对调用方暴露,产品经理并不关心你这个页面中什么元素定位,他也不懂。

class LoginPage:
	username_loc=(By.ID,"idInput")
    password_loc =(By.ID,"pwdInput")
    submit_loc =(By.ID,"loginBtn")
    span_loc=(By.CSS_SELECTOR,"div.error-tt>p")
    dynpw_loc =(By.ID,"lbDynPw")
    userid_loc =(By.ID,"spnUid")
    def __init__(self, driver):
        self.driver = driver
    def login(self):
        self.driver.find_element(*self.username_loc).clear()
        self.driver.find_element(*self.username_loc).send_keys("xxxxx")
        self.driver.find_element(*self.password_loc).clear()
        self.driver.find_element(*self.password_loc).send_keys("xxxxxx")
        self.driver.find_element(*self.submit_loc).click()

这种方式把元素定位方式也分离了。但是这种元素定位的表达式可读性也不是很强,可以换用 property 方式来表示元素,所有的元素统一放在一起,修改起来也比较方便。

class LoginPage:
    def __init__(self, driver)
    	self.driver = driver
    @property
    def username_element(self):
        return self.driver.find_element('id', 'idInput')
    def password_element(self):
        return self.driver.find_element('id', 'pwdInput')
    def submit_element(self):
        return self.driver.find_element('id', 'loginBtn')
    def login(self, name, password):
        self.username_element.send_keys(name)
        self.password_element.send_keys(password)
        self.submit_element.click()

第三种方式可以充分利用Python的描述符特性,你会发现很多序列化库或者ORM框架都有类似的用法。

class LoginPage:
    def __init__(self, driver)
    	self.driver = driver
    username = Element(css='#idInput', desc='用户名输入框')
    password = Element(css='#pwdInput', desc='密码输入框')
    confirm = Element(css='#loginBtn', desc='登录确认按钮')
   	def login(self, name, password):
        self.username.send_keys(name)
        self.password.send_keys(password)
        self.confirm.click()

而 Element 类可以通过 Python 描述符实现,这里为了方便,只定义了xpath的元素定位方法:

class Element:
    def __init__(self,xpath=None,desc=''):
        self.xpath = xpath
        self.desc = desc
    def __get__(self, instance, owner):
        driver = instance.browser
        el = driver.find_element('xpath', self.xpath)
        return el

PO模式和DDD

PO模式是DDD(领域驱动设计)的一个简单实现,但是还不够彻底。如果要在自动化测试中贯彻DDD,我觉得还有一些可以优化的空间。

首先某一个业务不一定只是单个页面的操作,比如登录不一定只涉及到LoginPage这个页面,因此直接在LoginPage中编写login函数就不是很合理。对于调用方来说,应该明确说明的是谁在登录,而不是指某个页面。像这样:

user.login()
# or
login(user)

我们编写的代码就像是自然语言,任何懂英语的人都知道代码在做什么,在DDD中,叫做领域特定语言(DSL), 要实现这种逻辑,在Page类和调用中间应该还会有一个层级来封装user。

其次,Page页面会依赖更底层的资源,比如组件,元素类型。因此在 Page 类的下方应该会使用 InputElement, ButtonElement 、SelectElement 这样的元素类和 HeaderComponent、FooterComponent 这样的组件类。

class LoginPage:
	username_filed = InputElement('xxx')
	password_filed = PasswordElement('xxx')

领域驱动设计对于大型项目梳理业务、同步业务、沟通业务是非常有帮助的,是一种以业务为中心的设计范式。PO模式对于DDD的小范围应用,以及具体了足够多的好处:

  • 便于维护。每一个页面的操作都被单独的存放在一个类文件中,当前端页面被修改之后,只需要找到对应类文件进行修改,其他的代码并不需要进行修改,这符合单一职责原则。
  • 便于重复使用。在进行自动化测试的时候,一个测试由多个测试步骤组成,这些测试步骤可能涉及到多个页面的操作。而用例与用例之间的操作可能重合。PO模式可以重复利用这些测试步骤,简化代码的编写。
  • 提高了可读性。页面的操作都被以函数的形式封装起来了。函数名就具备注释的作用,其他人阅读代码时可以通过函数了解业务。

到此这篇关于PO模式在selenium自动化测试框架有什么好处的文章就介绍到这了,更多相关selenium自动化测试内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python Mysql自动备份脚本
Jul 14 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
Feb 03 Python
pip安装时ReadTimeoutError的解决方法
Jun 12 Python
python3解析库lxml的安装与基本使用
Jun 27 Python
Python+OpenCV图片局部区域像素值处理详解
Jan 23 Python
简单了解Python生成器是什么
Jul 02 Python
基于pandas中expand的作用详解
Dec 17 Python
Pytorch 中retain_graph的用法详解
Jan 07 Python
对django 2.x版本中models.ForeignKey()外键说明介绍
Mar 30 Python
python多线程实现同时执行两个while循环的操作
May 02 Python
Anaconda的安装与虚拟环境建立
Nov 18 Python
发工资啦!教你用Python实现邮箱自动群发工资条
May 10 Python
Python IO文件管理的具体使用
Python实现Excel文件的合并(以新冠疫情数据为例)
Python中三种花式打印的示例详解
Mar 19 #Python
Python学习之包与模块详解
Python requests用法和django后台处理详解
Mar 19 #Python
Python实现Hash算法
Mar 18 #Python
python实现会员信息管理系统(List)
Mar 18 #Python
You might like
php中的三元运算符使用说明
2011/07/03 PHP
PHP简单实现“相关文章推荐”功能的方法
2014/07/19 PHP
php实现MySQL数据库备份与还原类实例
2014/12/09 PHP
laravel 错误处理,接口错误返回json代码
2019/10/25 PHP
[对联广告] JS脚本类
2006/08/27 Javascript
asp javascript 实现关闭窗口时保存数据的办法
2007/11/24 Javascript
JS 页面计时器示例代码
2013/10/28 Javascript
JavaScript/Js脚本处理html元素的自定义属性解析(亲测兼容Firefox与IE)
2013/11/25 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
2014/03/28 Javascript
jQuery菜单插件superfish使用指南
2015/04/21 Javascript
JavaScript实现select添加option
2015/07/03 Javascript
JavaScript实现页面跳转的几种常用方式
2015/11/28 Javascript
JavaScript知识点总结(五)之Javascript中两个等于号(==)和三个等于号(===)的区别
2016/05/31 Javascript
textarea 在浏览器中固定大小和禁止拖动的实现方法
2016/12/03 Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
2018/02/16 Javascript
js将键值对字符串转为json字符串的方法
2018/03/30 Javascript
vue项目首屏打开速度慢的解决方法
2019/03/31 Javascript
vue Cli 环境删除与重装教程 - 版本文档
2020/09/11 Javascript
[52:20]VP vs VG Supermajor小组赛 B组胜者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
python实现根据用户输入从电影网站获取影片信息的方法
2015/04/07 Python
在Python中操作字典之clear()方法的使用
2015/05/21 Python
python的多重继承的理解
2017/08/06 Python
python numpy和list查询其中某个数的个数及定位方法
2018/06/27 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
2020/03/01 Python
使用OpenCV实现道路车辆计数的使用方法
2020/07/15 Python
海蓝之谜(LA MER)澳大利亚官方商城:全球高端奢华护肤品牌
2017/10/27 全球购物
草莓网中国:StrawberryNet中国
2020/08/17 全球购物
在weblogic中发布ejb需涉及到哪些配置文件
2012/01/17 面试题
母亲节演讲稿范文
2014/01/02 职场文书
小学后勤管理制度
2014/01/14 职场文书
装修五一活动策划案
2014/01/23 职场文书
大四自我鉴定
2014/02/08 职场文书
网站客服岗位职责
2014/04/05 职场文书
酒店总经理岗位职责范本
2014/08/08 职场文书
2014年团员学习十八大思想汇报
2014/09/13 职场文书
Windows Server 版本 20H2 于 8 月 9 日停止支持,Win10 版本 21H1 将于 12 月结束支
2022/07/23 数码科技