selenium- PO模式

1|0一、思想:

PO模式:
  PageObject,从最初自动化是基于QTP来实现的,通过录制的形式,自动生成脚本,通过定义对象库来实现对页面的元素的收集,升级到关键字驱动的形式来实现自动化(通过封装对元素的操作,来实现关键字驱动),再升级到PageObject,将系统以页面来进行区分,针对不同的页面,基于页面的元素及当前页面所实现的业务,将其定义为一个完整的页面对象。然后对这个页面对象进行操作。在PO中,通过分层的形式,来定义出不同页面的操作内容:

  1、BasePage:基础层,用于提供最为底层的功能,让其他页面对象可以直接进行继承
  2、Page:页面层,用于提供元素的获取,各个元素的操作方法的封装
  3、业务层:通过这一层的调用,传入参数,进行自动化的运行

优点:
1、针对于指定的被测业务系统的流程,执行自动化时非常简便
缺点:
1、对于多个系统的复用性相对较差

2|0二、PO实现实例

下面,以安居客登录为例

2|12.1 定义公用功能部分 basepage.py

# -*- coding:utf-8 -*- from public.common.log import Logger from config import globalparam from selenium.common.exceptions import NoSuchElementException import os import time logger = Logger(logger='BasePage').getlog() class BasePage: """测试基类""" def __init__(self, driver): self.driver = driver @staticmethod def isdisplayed(element): """元素是否存在""" value = element.is_displayed() return value @staticmethod def sleep(secondes): """强制等待""" time.sleep(secondes) logger.info('Sleep for %d seconds' % secondes) def open_url(self,url): self.driver.get(url) def forward(self): """浏览器前进""" self.driver.forward() logger.info("Click forward on current page.") def back(self): """浏览器后退""" self.driver.back() logger.info("Click back on current page.") def wait(self,seconds): """隐式等待""" self.driver.implicitly_wait(seconds) logger.info("wait for %d seconds." % seconds) def close(self): """关闭当前窗口""" try: self.driver.close() logger.info("Closing and quit the browser.") except NameError as e: logger.info("Faile to quit the browser with %s" %e) def get_img(self): """截图""" rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())) screen_name = os.path.join(globalparam.test_img_path,'%s.png' % rq) # noinspection PyBroadException try: self.driver.get_screenshot_as_file(screen_name) logger.info("Had take screenshot and save to folder : /screenshots") except NameError as e: logger.error("Failed to take screenshot! %s" % e) self.get_img() def find_element(self, selector): """定位元素""" by = selector[0] value = selector[1] element = None if by in ['id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath']: # noinspection PyBroadException try: if by == 'id': element = self.driver.find_element_by_id(value) elif by == 'name': element = self.driver.find_element_by_name(value) elif by == 'class': element = self.driver.find_element_by_class_name(value) elif by == 'tag': element = self.driver.find_element_by_tag_name(value) elif by == 'link': element = self.driver.find_element_by_link_text(value) elif by == 'plink': element = self.driver.find_element_by_partial_link_text(value) elif by == 'css': element = self.driver.find_element_by_css_selector(value) elif by == 'xpath': element = self.driver.find_element_by_xpath(value) else: logger.error('Not find the element') logger.info("Had find the element! ,by %s via value :%s " %(by,value)) # logger.info('元素定位成功。定位方式:%s,使用的值%s:' % (by, value)) return element except NoSuchElementException as e: logger.error("NoSuchElementException %s " %e) self.get_img() # 调用截图 else: logger.error('Please enter a valid type of targeting elements') def type(self, selector, value): """输入内容""" element = self.find_element(selector) # element.clear() logger.info('clear input_box') # noinspection PyBroadException try: element.send_keys(value) logger.info('input is:%s' % value) except BaseException: logger.error('Failed to type in input box', exc_info=1) self.get_img() #输入并确认 def type_enter(self,selector,value): try: element = self.find_element(selector) element.send_keys(value) time.sleep(1) element.send_keys(Keys.ENTER) except Exception as e: logger.info("Failed to type_and_enter with %s" % e) self.get_img() raise def click(self, selector): """点击元素""" element = self.find_element(selector) # noinspection PyBroadException try: element.click() logger.info('"The element \' %s \' was clicked." % element.text') except BaseException: display = self.isdisplayed(element) if display is True: self.sleep(3) element.click() logger.info('The element was clicked') else: self.get_img() logger.error('Failed to click the element', exc_info=1) def right_click(self,selector): """右击元素""" element = self.find_element(selector) try: ActionChains(self.driver).context_click(element).perform() logger.info("The element \' %s \' was clicked." % element.text) except NameError as e: logger.error("Failed to right_click the element with %s" % e) self.get_img() def double_click(self,selector): """双击""" element = self.find_element(selector) try: ActionChains(self.driver).double_click(element).perform() except Exception as e: logger.info("Failed to double_click the element with %s" % e) self.get_img() raise def move_to_element(self,selector): """鼠标移到元素上""" try: element = self.find_element(selector) ActionChains(self.driver).move_to_element(element).perform() except Exception as e: logger.info("Failed to move_to_element the element with %s" % e) self.get_img() raise def drag_and_drop(self, element_selector,ta_selector): """拖拽""" try: element_drag = self.find_element(element_selector) taget_drop = self.find_element(ta_selector) ActionChains(self.driver).drag_and_drop(element_drag,taget_drop).perform() except Exception as e: logger.info("Failed to drag_and_drop the element with %s" % e) self.get_img() raise def refresh(self): """刷新""" self.driver.refresh() def submit(self,selector): """submit""" try: element = self.find_element(selector) element.submit() except Exception as e: logger.info("Failed to submit the element with %s" % e) self.get_img() def get_attribute(self,selector,attribute): """获取元素属性""" try: element = self.find_element(selector) return element.get_attribute(attribute) except Exception as e: logger.info("Failed to get_attribute with %s" % e) self.get_img() raise def get_text(self,selector): """获取元素的文本信息""" try: return self.find_element(selector).text except Exception as e: logger.info("Failed to get_text with %s" % e) self.get_img() def dismiss_alert(self): """弹窗 alert——取消""" self.driver.switch_to.alert.dismiss() def clear(self,selector): """清除文本框""" element = self.find_element(selector) try: element.clear() logger.info("Clear text in input box before typing.") except NameError as e: logger.error("Failed to clear in input box with %s" % e) self.get_img() def use_js(self, js): """调用js""" # noinspection PyBroadException try: self.driver.execute_script(js) logger.info('successful,js contents is:%s' % js) except BaseException: logger.error('js error', exc_info=1) def switch_menue(self, parentelement, secelement, targetelement): """三级菜单切换""" self.sleep(3) # noinspection PyBroadException try: self.driver.switch_to_default_content() self.click(parentelement) logger.info('成功点击一级菜单:%s' % parentelement) self.click(secelement) logger.info('成功点击二级菜单:%s' % secelement) self.click(targetelement) logger.info('成功点击三级菜单:%s' % targetelement) except BaseException: logger.error('切换菜单报错', exc_info=1) def switch_ifarme(self, selector): """切换ifarme""" element = self.find_element(selector) # noinspection PyBroadException try: self.driver.switch_to.frame(element) logger.info('Successful to switch_to_frame! ') except BaseException: logger.error('Failed to switch_to_frame', exc_info=1) def quit_iframe(self): """退出当前iframe""" self.driver.switch_to_default_content() def get_title(self): """获取title""" title = self.driver.title logger.info('Current page title is:%s' % title) return title def quit(self): """关闭浏览器""" self.driver.quit() logger.info('quit the browser')

2|22.2 页面封装 login.py

每个操作封装成一个个小组件.

这里需要注意的是

self.findElement(*self.pwtab_loc).click() 参数中,带*号,为什么要带星号,因为我们参数是一个元组.中间有By.ID这样的对像,如果不加会有问题.
#coding:utf-8 from selenium.webdriver.common.by import By from selenium import webdriver class LoginPage(BasePage): #定位元素 username_loc = (By.ID,"pwdUserNameIpt") password_loc = (By.ID,"pwdIpt") pwtab_loc = (By.ID,"pwdTab") btn_loc = (By.ID,"pwdSubmitBtn") switchFrame = 0 #打开页面 def open_url(self): self.page_open(self.base_url,self.page_title) #切换frame def switch_to_f(self): self.switch_to_frame(self.switchFrame) #切换登录方式 def switch_login(self): self.findElement(*self.pwtab_loc).click() #输入用户名 def inputUserName(self,username): self.findElement(*self.username_loc).send_keys(username) #输入pndc def inputPassWord(self,password): self.findElement(*self.password_loc).send_keys(password) #单击登录按钮 def clickLogin(self): self.findElement(*self.btn_loc).click() if __name__=="__main__": driver = webdriver.Firefox() driver.implicitly_wait(30) url = 'https://login.anjuke.com/login/form?history=aHR0cHM6Ly9zaGFuZ2hhaS5hbmp1a2UuY29tLw==' username ='123' password='' Login_page = LoginPage(url,driver,u'登录') Login_page.open_url() Login_page.switch_to_f() Login_page.switch_login() Login_page.inputUserName(username) Login_page.inputPassWord(password) Login_page.clickLogin()

2|32.3 pytest 用例封装


__EOF__

本文作者😎
本文链接https://www.cnblogs.com/dongye95/p/14447495.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   dongye95  阅读(362)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2019-02-25 python——操作系统的发展史
点击右上角即可分享
微信分享提示