Python Selenium设计模式

Stella981
• 阅读 518

Python Selenium设计模式

前言


本文就python selenium自动化测试实践中所需要的POM设计模式进行分享,以便大家在实践中对POM的特点、应用场景和核心思想有一定的理解和掌握。

为什么要用POM

基于python selenium2开始UI级自动化测试并不是多么艰巨的任务。**只需要定位到元素,执行对应的操作即可。**下面我们看一下这个简单的脚本实现百度搜索。

from selenium import webdriverimport timedriver = webdriver.Firefox()driver.implicitly_wait(30)# 启动浏览器,访问百度driver.get("http://www.baidu.com")# 定位 百度搜索框,并输入seleniumdriver.find_element_by_id("kw").send_keys("selenium")# 定位 百度一下 按钮并单击进行搜索driver.find_element_by_id("su").click()time.sleep(5)driver.quit()

从上述代码来看,我们所能做的就是定位到元素,然后进行键盘输入或鼠标动作。就这个小程序而已,维护起来看起来是很容易的。但随着时间的迁移,测试套件将持续的增长。脚本也将变得越来越臃肿庞大。如果变成我们需要维护10个页面,100个页面,甚至1000个呢?那页面元素的任何改变都会让我们的脚本维护变得繁琐复杂,而且变得耗时易出错。

那怎么解决呢? 在自动化测试中,引入了Page Object Model(POM):页面对象模式来解决,POM能让我们的测试代码变得可读性更好,高可维护性,高复用性。

下图为非POM和POM对比图:

Python Selenium设计模式

POM是什么

  • 页面对象模型(POM)是一种设计模式,用来管理维护一组web元素集的对象库

  • 在POM下,应用程序的每一个页面都有一个对应的page class

  • 每一个page class维护着该web页的元素集和操作这些元素的方法

  • page class中的方法命名最好根据其对应的业务场景进行,例如通常登录后我们需要等待几秒中,我们可以这样命名该方法: waitingForLoginSuccess().

下面我们看看POM的代码目录组织示例:

Python Selenium设计模式

POM的优势

  1. POM提供了一种在UI层操作、业务流程与验证分离的模式,这使得测试代码变得更加清晰和高可读性

  2. 对象库与用例分离,使得我们更好的复用对象,甚至能与不同的工具进行深度结合应用

  3. 可复用的页面方法代码会变得更加优化

  4. 更加有效的命名方式使得我们更加清晰的知道方法所操作的UI元素。例如我们要回到首页,方法名命名为: gotoHomePage(),通过方法名即可清晰的知道具体的功能实现。

POM实现示例

下面我们看下使用POM百度搜索 POM代码示例: 看先下代码组织结构如下:

Python Selenium设计模式

# basePage.py代码如下# _*_ coding:utf-8 _*___author__ = '苦叶子'import sysreload(sys)sys.setdefaultencoding("utf-8")# pages基类class Page(object):    """        Page基类,所有page都应该继承该类    """    def __init__(self, driver, base_url=u"http://www.baidu.com"):        self.driver = driver        self.base_url = base_url        self.timeout = 30        def find_element(self, *loc):        return self.driver.find_element(*loc)       def input_text(self, loc, text):        self.find_element(*loc).send_keys(text)                def click(self, loc):        self.find_element(*loc).click()             def get_title(self):        return self.driver.title

# searchPage.py 代码如下# _*_ coding:utf-8 _*___author__ = '苦叶子'import sysfrom selenium.webdriver.common.by import Byfrom pages.basePage import Pagereload(sys)sys.setdefaultencoding("utf-8")# 百度搜索pageclass SearchPage(Page):    # 元素集        # 搜索输入框    search_input = (By.ID, u'kw')        # 百度一下 按钮    search_button = (By.ID, u'su')        def __init__(self, driver, base_url=u"http://www.baidu.com"):        Page.__init__(self, driver, base_url)           def gotoBaiduHomePage(self):        print u"打开首页: ", self.base_url        self.driver.get(self.base_url)                     def input_search_text(self, text=u"开源优测"):        print u"输入搜索关键字:开源优测 "        self.input_text(self.search_input, text)           def click_search_btn(self):        print u"点击 百度一下  按钮"        self.click(self.search_button)

# testSearchPage.py代码如下# _*_ coding:utf-8 _*___author__ = '苦叶子'import unittestimport sysfrom selenium import webdriverfrom pages.searchPage import SearchPagereload(sys)sys.setdefaultencoding("utf-8")# 百度搜索测试class TestSearchPage(unittest.TestCase):        def setUp(self):        self.driver = webdriver.Ie()            def testSearch(self):        driver = self.driver                # 百度网址        url = u"http://www.baidu.com"        # 搜索文本        text = u"开源优测"        # 期望验证的标题        assert_title = u"开源优测_百度搜索"        print assert_title                search_Page = SearchPage(driver, url)                    # 启动浏览器,访问百度首页        search_Page.gotoBaiduHomePage()                         # 输入 搜索词        search_Page.input_search_text(text)                              # 单击 百度一下 按钮进行搜索        search_Page.click_search_btn()                                     # 验证标题        self.assertEqual(search_Page.get_title(), assert_title)                                    def tearDown(self):        self.driver.quit()

# 主入口程序代码如下# _*_ coding:utf-8 _*___author__ = '苦叶子'import unittestimport sysfrom common import HTMLTestRunnerfrom testcase.testSearchPageimport TestSearchPagereload(sys)sys.setdefaultencoding("utf-8")if __name__ == '__main__':    testunit = unittest.TestSuite()    testunit.addTest(TestSearchPage('testSearch'))       # 定义报告输出路径    htmlPath = u"page_demo_Report.html"    fp = file(htmlPath, "wb")        runner = HTMLTestRunner.HTMLTestRunner(stream=fp,           title=u"百度测试",           description=u"测试用例结果")        runner.run(testunit)        fp.close()

按照如图所示组织代码结构,输入如上代码,执行以下命令运行,会在当前目录生成测试报告:

python main.py

总结

最后做个总结,所有代码请手动输入,不要直接拷贝。再次对POM进行小结

  1. POM是selenium webdriver自动化测试实践对象库设计模式

  2. POM使得测试脚本更易于维护

  3. POM通过对象库方式进一步优化了元素、用例、数据的维护组织

更多精彩

webdriver介绍&与Selenium RC的比较

Python Selenium Webdriver安装手册

创建你的第一个webdriver python代码

基于Excel参数化你的Selenium2测试

python selenium2示例 - 生成 HTMLTestRunner 测试报告

python selenium2示例 - 同步机制

python selenium2示例 - 日志管理

python selenium2 架构说明

python selenium2源码分析概要

扫一扫加我微信,注明:入群,加入微信群

Python Selenium设计模式

扫一扫关注开源优测公众号,原创文章首发平台

Python Selenium设计模式

在公众号里回复一下关键字获取对应的系列文章

物联网

appium

大数据测试

RobotFramework

Python

自动驾驶

jmeter

selenium

jenkins

接口测试

Python Selenium设计模式

本文分享自微信公众号 - 开源优测(DeepTest)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这