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 相关文章推荐
python3模拟百度登录并实现百度贴吧签到示例分享(百度贴吧自动签到)
Feb 24 Python
python基础教程之序列详解
Aug 29 Python
Python使用matplotlib实现在坐标系中画一个矩形的方法
May 20 Python
Python基本语法经典教程
Mar 11 Python
python利用smtplib实现QQ邮箱发送邮件
May 20 Python
Python运维之获取系统CPU信息的实现方法
Jun 11 Python
python实现五子棋小游戏
Mar 25 Python
Python获取时间戳代码实例
Sep 24 Python
python 实现多维数组转向量
Nov 30 Python
Python OpenCV去除字母后面的杂线操作
Jul 05 Python
2020年10款优秀的Python第三方库,看看有你中意的吗?
Jan 12 Python
python中Array和DataFrame相互转换的实例讲解
Feb 03 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(1)
2006/10/09 PHP
php转换颜色为其反色的方法
2015/04/27 PHP
PHP模板引擎Smarty自定义变量调解器用法
2016/04/11 PHP
PHP页面输出搜索后跳转下一页的处理方法
2016/09/30 PHP
PHP检测一个数组有没有定义的方法步骤
2019/07/20 PHP
jquery重新播放css动画所遇问题解决
2013/08/21 Javascript
javascript中String对象的slice()方法分析
2014/12/20 Javascript
javascript this详细介绍
2016/09/19 Javascript
解析如何利用iframe标签以及js制作时钟
2016/12/08 Javascript
实现JavaScript高性能的数据存储
2016/12/11 Javascript
Webpack优化配置缩小文件搜索范围
2017/12/25 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
JS实现根据指定值删除数组中的元素操作示例
2018/08/02 Javascript
vue中如何去掉空格的方法实现
2018/11/09 Javascript
vue 父组件给子组件传值子组件给父组件传值的实例代码
2019/04/15 Javascript
js的新生代垃圾回收知识点总结
2019/08/22 Javascript
浅析vue-router中params和query的区别
2019/12/24 Javascript
VueX模块的具体使用(小白教程)
2020/06/05 Javascript
Python编程中对super函数的正确理解和用法解析
2016/07/02 Python
Python中的异常处理相关语句基础学习笔记
2016/07/11 Python
python使用正则表达式的search()函数实现指定位置搜索功能
2017/11/10 Python
python Opencv将图片转为字符画
2021/02/19 Python
创建pycharm的自定义python模板方法
2018/05/23 Python
python 用所有标点符号分隔句子的示例
2019/07/15 Python
Python爬虫:url中带字典列表参数的编码转换方法
2019/08/21 Python
Win10里python3创建虚拟环境的步骤
2020/01/31 Python
Django使用rest_framework写出API
2020/05/21 Python
CSS3弹性伸缩布局之box布局
2016/07/12 HTML / CSS
CSS3的Flexbox布局的简明入门指南
2016/04/08 HTML / CSS
HTML5的video标签的浏览器兼容性增强方案分享
2016/05/19 HTML / CSS
如何在.net Winform里面显示PDF文档
2012/09/11 面试题
施工安全承诺书
2014/05/22 职场文书
公司离职证明标准范本
2014/10/05 职场文书
党员查摆问题及整改措施
2014/10/10 职场文书
Python使用random模块实现掷骰子游戏的示例代码
2021/04/29 Python
Python包argparse模块常用方法
2021/06/04 Python